提交 bf4e9501 编写于 作者: L lana

Merge

......@@ -21,4 +21,4 @@
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
tzdata2009l
tzdata2009r
......@@ -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)
# <a href="http://www.aad.gov.au/default.asp?casid=37079">
# http://www.aad.gov.au/default.asp?casid=37079
# </a>
#
# We have more background information here:
# <a href="http://www.timeanddate.com/news/time/antarctica-new-times.html">
# http://www.timeanddate.com/news/time/antarctica-new-times.html
# </a>
# 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:
# <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
# Casey Weather (1998-02-26)
......
......@@ -21,7 +21,6 @@
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# <pre>
# 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"
# <a href="http://www.thedailystar.net/newDesign/news-details.php?nid=107021">
# http://www.thedailystar.net/newDesign/news-details.php?nid=107021
# </a>
# or
# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html">
# http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html
# </a>
# 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:
# <a href="http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html">
# http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html
# </a>
# 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
# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
# http://www.hko.gov.hk/gts/time/Summertime.htm
# </a>.
# From Arthur David Olson (2009-10-28):
# Here are the dates given at
# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
# http://www.hko.gov.hk/gts/time/Summertime.htm
# </a>
# 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."
# <a href="http://www.thenews.com.pk/updates.asp?id=87168">
# http://www.thenews.com.pk/updates.asp?id=87168
# </a>
# 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"
# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2">
# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2
# </a>
# or
# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm">
# http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm
# </a>
# 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:
# <a href="http://www.thenews.com.pk/top_story_detail.asp?Id=24742">
# http://www.thenews.com.pk/top_story_detail.asp?Id=24742
# </a>
# "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:
# <a href="http://www.timeanddate.com/news/time/pakistan-ends-dst09.html">
# http://www.timeanddate.com/news/time/pakistan-ends-dst09.html
# </a>
# 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
# </a>
# 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:
# <a href="http://www.safa.ps/ara/?action=showdetail&seid=4158">
# http://www.safa.ps/ara/?action=showdetail&seid=4158
# </a>
# (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:
# <a href="http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html">
# http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html
# </a>
# 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):
# <a href="http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
# http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
# </a>
# or
# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html>
# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
# </a>
# 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
# </a>
# 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:
# <a href="http://www.sana.sy/ara/2/2009/09/29/247012.htm">
# http://www.sana.sy/ara/2/2009/09/29/247012.htm (Arabic)
# </a>
# 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
......
......@@ -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
# </a>
# 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:
# <a href="http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html">
# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
# </a>
# 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
......
......@@ -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)
# <a href="http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archiv">
# http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archive/2009/09/14/991633.htm
# </a>
# or Russian-English translation by WorldTimeZone.com with reference
# map to local region and new Russia Time Zone map after March 28, 2010
# <a href="http://www.worldtimezone.com/dst_news/dst_news_russia03.html">
# http://www.worldtimezone.com/dst_news/dst_news_russia03.html
# </a>
#
# 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
......
......@@ -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
# </a>
# From fullinet (2009-10-18):
# As announced in
# <a hef="http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356">
# http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356
# </a>
# (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
# <a href="http://www.timeanddate.com/news/time/san-luis-new-time-zone.html">
# 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
# <a href="http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276>"
# http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276
# </a>
# 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
......
......@@ -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
......
/*
* 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 <code>NumericShaper</code> 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);
* </pre></blockquote>
*
* <p><b>Bit mask- and enum-based Unicode ranges</b></p>
*
* <p>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:
* <blockquote><pre>
* NumericShaper.ARABIC | NumericShaper.TAMIL
* </pre></blockquote>
* or creating a {@code Set} with the {@link NumericShaper.Range}
* constants, such as:
* <blockquote><pre>
* EnumSet.of(NumericShaper.Scirpt.ARABIC, NumericShaper.Range.TAMIL)
* </pre></blockquote>
* The enum-based ranges are a super set of the bit mask-based ones.
*
* <p>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).
*
* <p>The <code>Range</code> 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:
* <blockquote><pre>
* NumericShaper.getContextualShaper(NumericShaper.ARABIC |
* NumericShaper.TAMIL,
* NumericShaper.EUROPEAN);
* </pre></blockquote>
* can be written using this enum as:
* <blockquote><pre>
* NumericShaper.getContextualShaper(EnumSet.of(
* NumericShaper.Range.ARABIC,
* NumericShaper.Range.TAMIL),
* NumericShaper.Range.EUROPEAN);
* </pre></blockquote>
*
* @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<Range>() {
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<Range> ranges) {
int m = 0;
for (Range range : ranges) {
int index = range.ordinal();
if (index < NUM_KEYS) {
m |= 1 << index;
}
}
return m;
}
private static Set<Range> maskToRangeSet(int mask) {
Set<Range> 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<Range>} indicating which Unicode ranges to
* shape. {@code null} for the bit mask-based API.
*
* @since 1.7
*/
private transient Set<Range> 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.
*
* <p>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<<key)) == 0)) {
++key;
......@@ -644,11 +812,26 @@ public final class NumericShaper implements java.io.Serializable {
* @return a non-contextual numeric shaper
* @throws IllegalArgumentException if the range is not a single range
*/
static public NumericShaper getShaper(int singleRange) {
public static NumericShaper getShaper(int singleRange) {
int key = getKeyFromMask(singleRange);
return new NumericShaper(key, singleRange);
}
/**
* Returns a shaper for the provided Unicode
* range. All Latin-1 (EUROPEAN) digits are converted to the
* corresponding decimal digits of the specified Unicode range.
*
* @param singleRange the Unicode range given by a {@link
* NumericShaper.Range} constant.
* @return a non-contextual {@code NumericShaper}.
* @throws NullPointerException if {@code singleRange} is {@code null}
* @since 1.7
*/
public static NumericShaper getShaper(Range singleRange) {
return new NumericShaper(singleRange, EnumSet.of(singleRange));
}
/**
* Returns a contextual shaper for the provided unicode range(s).
* Latin-1 (EUROPEAN) digits are converted to the decimal digits
......@@ -663,11 +846,33 @@ public final class NumericShaper implements java.io.Serializable {
* @param ranges the specified Unicode ranges
* @return a shaper for the specified ranges
*/
static public NumericShaper getContextualShaper(int ranges) {
public static NumericShaper getContextualShaper(int ranges) {
ranges |= CONTEXTUAL_MASK;
return new NumericShaper(EUROPEAN_KEY, ranges);
}
/**
* Returns a contextual shaper for the provided Unicode
* range(s). The Latin-1 (EUROPEAN) digits are converted to the
* decimal digits corresponding to the range of the preceding
* text, if the range is one of the provided ranges.
*
* <p>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<Range> 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
* <code>defaultContext</code> 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<Range> 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<Range> 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 {
* <blockquote>
* <code>if ((shaper.getRanges() & shaper.ARABIC) != 0) { ... </code>
* </blockquote>
*
* <p>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<Range> 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<<ctxKey)) == 0) {
ctxKey = EUROPEAN_KEY;
}
base = bases[ctxKey];
minDigit = ctxKey == ETHIOPIC_KEY ? '1' : '0'; // Ethiopic doesn't use decimal zero
}
}
}
}
}
private void shapeContextually(char[] text, int start, int count, Range ctxKey) {
if (ctxKey == null) {
ctxKey = Range.EUROPEAN;
}
Range lastKey = ctxKey;
int base = ctxKey.getDigitBase();
char minDigit = (char)('0' + ctxKey.getNumericBase());
for (int i = start, end = start + count; i < end; ++i) {
char c = text[i];
if (c >= 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<<ctxKey)) == 0) {
ctxKey = EUROPEAN_KEY;
Range newKey = rangeForCodePoint(c);
if (newKey != lastKey) {
lastKey = newKey;
ctxKey = newKey;
if (rangeSet.contains(Range.EUROPEAN)
&& (ctxKey == Range.ARABIC || ctxKey == Range.EASTERN_ARABIC)) {
ctxKey = Range.EASTERN_ARABIC;
} else if (!rangeSet.contains(ctxKey)) {
ctxKey = Range.EUROPEAN;
}
base = bases[ctxKey];
minDigit = ctxKey == TAMIL_KEY ? '\u0031' : '\u0030'; // Tamil doesn't use decimal zero
base = ctxKey.getDigitBase();
minDigit = (char)('0' + ctxKey.getNumericBase());
}
}
}
......@@ -852,12 +1190,28 @@ public final class NumericShaper implements java.io.Serializable {
* @see java.lang.Object#hashCode
*/
public int hashCode() {
return mask;
int hash = mask;
if (rangeSet != null) {
// Use the CONTEXTUAL_MASK bit only for the enum-based
// NumericShaper. A deserialized NumericShaper might have
// bit masks.
hash &= CONTEXTUAL_MASK;
hash ^= rangeSet.hashCode();
}
return hash;
}
/**
* Returns true if the specified object is an instance of
* <code>NumericShaper</code> and shapes identically to this one.
* Returns {@code true} if the specified object is an instance of
* <code>NumericShaper</code> 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"}.
* <blockquote><pre>
* NumericShaper ns1 = NumericShaper.getShaper(NumericShaper.ARABIC);
* NumericShaper ns2 = NumericShaper.getShaper(NumericShaper.Range.ARABIC);
* System.out.println(ns1.equals(ns2));
* </pre></blockquote>
*
* @param o the specified object to compare to this
* <code>NumericShaper</code>
* @return <code>true</code> if <code>o</code> 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<Range> 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();
}
}
......@@ -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();
......
......@@ -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;
}
......
......@@ -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 <code>JTable</code> 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) {
......
......@@ -292,7 +292,7 @@ public class JTextField extends JTextComponent implements SwingConstants {
*/
@Override
public boolean isValidateRoot() {
return SwingUtilities2.getViewport(this) == null;
return SwingUtilities.getParentViewport(this) == null;
}
......
......@@ -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;
}
......
......@@ -1969,6 +1969,66 @@ public class SwingUtilities implements SwingConstants
}
/**
* 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:
* <pre>
* JViewport port = null;
* Container parent = component.getParent();
* // not recommended any more
* if(parent instanceof JViewport) {
* port = (JViewport) parent;
* }
* </pre>
* Here is the way to go:
* <pre>
* // the correct way:
* JViewport port = SwingUtilities.getParentViewport(component);
* </pre>
* @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
......
......@@ -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<File> files = new Vector<File>();
List<File> files = new ArrayList<File>();
// 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 {
* <code>null</code> if <code>dir</code> is <code>null</code>
*/
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:\\"));
}
/**
......
......@@ -71,33 +71,410 @@ public class LayerUI<V extends Component>
* Subclasses should override this method and use
* the specified {@code Graphics} object to
* render the content of the component.
* <p/>
* 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<V>}
* it can be safely cast to {@code JLayer<? extends V>}
*
* @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<? extends V> l = (JLayer<? extends V>) 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<? extends V> l) {
}
/**
* Called by the {@link #paint} method,
* subclasses should override this method
* to perform any custom painting operations.
* <p/>
* 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<? extends V> l) {
l.paint(g2);
}
/**
* Dispatches {@code AWTEvent}s for {@code JLayer}
* and <b>all it subcomponents</b> to this {@code LayerUI} instance.
* <p>
* To enable the {@code AWTEvent} of the particular type,
* you call {@link javax.swing.JLayer#setLayerEventMask}
* and <b>all its subcomponents</b> to this {@code LayerUI} instance.
* <p/>
* 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&lt;event&nbsp;type&gt;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<? extends V> 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.
* <p/>
* 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.
* <pre>
* 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);
* }
* </pre>
*
* @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<? extends V> l) {
}
/**
* Processes focus events occurring on the {@link JLayer}
* or any of its subcomponents.
* <p/>
* 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.
* <pre>
* 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);
* }
* </pre>
*
* @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<? extends V> l) {
}
/**
* Processes key events occurring on the {@link JLayer}
* or any of its subcomponents.
* <p/>
* 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.
* <pre>
* 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);
* }
* </pre>
*
* @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<? extends V> l) {
}
/**
* Processes mouse events occurring on the {@link JLayer}
* or any of its subcomponents.
* <p/>
* 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.
* <pre>
* 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);
* }
* </pre>
*
* @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<? extends V> l) {
}
/**
* Processes mouse motion event occurring on the {@link JLayer}
* or any of its subcomponents.
* <p/>
* 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.
* <pre>
* 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);
* }
* </pre>
*
* @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<? extends V> l) {
}
/**
* Processes mouse wheel event occurring on the {@link JLayer}
* or any of its subcomponents.
* <p/>
* 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.
* <pre>
* 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);
* }
* </pre>
*
* @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<? extends V> l) {
}
/**
* Processes input event occurring on the {@link JLayer}
* or any of its subcomponents.
* <p/>
* 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.
* <pre>
* 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);
* }
* </pre>
*
* @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<? extends V> l) {
}
/**
* Processes hierarchy event occurring on the {@link JLayer}
* or any of its subcomponents.
* <p/>
* 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.
* <pre>
* 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);
* }
* </pre>
*
* @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<? extends V> l) {
}
/**
* Processes hierarchy bounds event occurring on the {@link JLayer}
* or any of its subcomponents.
* <p/>
* 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.
* <pre>
* 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);
* }
* </pre>
*
* @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<? extends V> l) {
}
/**
......@@ -250,14 +627,29 @@ public class LayerUI<V extends Component>
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<? extends V> l) {
if ("dirty".equals(evt.getPropertyName())) {
l.repaint();
}
}
/**
......
......@@ -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();
......
......@@ -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
......
......@@ -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);
}
}
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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, E extends Throwable> T invoke(Callable<T> task, Class<E> exceptionClass)
throws InterruptedException, E {
try {
return getInvoker().invoke(task);
return invoker.invoke(task);
} catch (Exception e) {
if (e instanceof RuntimeException) {
// Rethrow unchecked exceptions
......
......@@ -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<Void>() {
public Void run() {
object.setAccessible(true);
return null;
}
});
}
private Class[] getClassArray(Object[] args) {
Class[] types = null;
if (args!=null) {
......
......@@ -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;
}
}
......@@ -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",
......
......@@ -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",
......
......@@ -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",
......
......@@ -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",
......
......@@ -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",
......
......@@ -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",
......
......@@ -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",
......
......@@ -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",
......
......@@ -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",
......
......@@ -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",
......
......@@ -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' */
......
......@@ -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<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
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
......
......@@ -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)) {
......
/*
* 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);
}
}
}
/*
* 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;
}
}
}
}
}
/*
* 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<HA> 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.");
}
}
}
/*
* 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());
}
}
}
});
}
}
/*
* 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<Void>() {
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);
}
}
/*
* 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);
}
}
}
/*
* 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 Checks that SwingLazyValue class correclty works
* @author Alexander Potochkin
* @run main SwingLazyValueTest
*/
import sun.swing.SwingLazyValue;
import javax.swing.*;
public class SwingLazyValueTest {
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");
}
}
}
/*
* 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 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.*;
public class TableTest {
public static void main(String[] args) throws Exception {
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");
}
}
}
/*
* 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<ProtectionDomain> weakRef;
public static void main(String[] args) throws Exception {
ProtectionDomain domain = new ProtectionDomain(null, null);
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
// this initialize ProxyLazyValues
UIManager.getLookAndFeel();
return null;
}
}, new AccessControlContext(new ProtectionDomain[]{domain}));
weakRef = new WeakReference<ProtectionDomain>(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<Object> bigLeak = new LinkedList<Object>();
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");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册