History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/util/TimeZoneNameUtility.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/util/TimeZoneNameUtility.java+235−0
@@ -0,0 +1,235 @@
1+/*
2+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.util;
27+
28+import java.lang.ref.SoftReference;
29+import java.util.Enumeration;
30+import java.util.LinkedList;
31+import java.util.List;
32+import java.util.Locale;
33+import java.util.Map;
34+import java.util.MissingResourceException;
35+import java.util.Set;
36+import java.util.concurrent.ConcurrentHashMap;
37+import java.util.spi.TimeZoneNameProvider;
38+import sun.util.calendar.ZoneInfo;
39+import sun.util.resources.LocaleData;
40+import sun.util.resources.OpenListResourceBundle;
41+
42+/**
43+ * Utility class that deals with the localized time zone names
44+ */
45+public final class TimeZoneNameUtility {
46+
47+ /**
48+ * cache to hold time zone resource bundles. Keyed by Locale
49+ */
50+ private static ConcurrentHashMap<Locale, SoftReference<OpenListResourceBundle>> cachedBundles =
51+ new ConcurrentHashMap<Locale, SoftReference<OpenListResourceBundle>>();
52+
53+ /**
54+ * cache to hold time zone localized strings. Keyed by Locale
55+ */
56+ private static ConcurrentHashMap<Locale, SoftReference<String[][]>> cachedZoneData =
57+ new ConcurrentHashMap<Locale, SoftReference<String[][]>>();
58+
59+ /**
60+ * get time zone localized strings. Enumerate all keys.
61+ */
62+ public static final String[][] getZoneStrings(Locale locale) {
63+ String[][] zones;
64+ SoftReference<String[][]> data = cachedZoneData.get(locale);
65+
66+ if (data == null || ((zones = data.get()) == null)) {
67+ zones = loadZoneStrings(locale);
68+ data = new SoftReference<String[][]>(zones);
69+ cachedZoneData.put(locale, data);
70+ }
71+
72+ return zones;
73+ }
74+
75+ private static final String[][] loadZoneStrings(Locale locale) {
76+ List<String[]> zones = new LinkedList<String[]>();
77+ OpenListResourceBundle rb = getBundle(locale);
78+ Enumeration<String> keys = rb.getKeys();
79+ String[] names = null;
80+
81+ while(keys.hasMoreElements()) {
82+ String key = keys.nextElement();
83+
84+ names = retrieveDisplayNames(rb, key, locale);
85+ if (names != null) {
86+ zones.add(names);
87+ }
88+ }
89+
90+ String[][] zonesArray = new String[zones.size()][];
91+ return zones.toArray(zonesArray);
92+ }
93+
94+ /**
95+ * Retrieve display names for a time zone ID.
96+ */
97+ public static final String[] retrieveDisplayNames(String id, Locale locale) {
98+ OpenListResourceBundle rb = getBundle(locale);
99+ return retrieveDisplayNames(rb, id, locale);
100+ }
101+
102+ private static final String[] retrieveDisplayNames(OpenListResourceBundle rb,
103+ String id, Locale locale) {
104+ LocaleServiceProviderPool pool =
105+ LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
106+ String[] names = null;
107+
108+ // Check whether a provider can provide an implementation that's closer
109+ // to the requested locale than what the Java runtime itself can provide.
110+ if (pool.hasProviders()) {
111+ names = pool.getLocalizedObject(
112+ TimeZoneNameGetter.INSTANCE,
113+ locale, rb, id);
114+ }
115+
116+ if (names == null) {
117+ try {
118+ names = rb.getStringArray(id);
119+ } catch (MissingResourceException mre) {
120+ // fall through
121+ }
122+ }
123+
124+ return names;
125+ }
126+
127+ private static final OpenListResourceBundle getBundle(Locale locale) {
128+ OpenListResourceBundle rb;
129+ SoftReference<OpenListResourceBundle> data = cachedBundles.get(locale);
130+
131+ if (data == null || ((rb = data.get()) == null)) {
132+ rb = LocaleData.getTimeZoneNames(locale);
133+ data = new SoftReference<OpenListResourceBundle>(rb);
134+ cachedBundles.put(locale, data);
135+ }
136+
137+ return rb;
138+ }
139+
140+ /**
141+ * Obtains a localized time zone strings from a TimeZoneNameProvider
142+ * implementation.
143+ */
144+ private static class TimeZoneNameGetter
145+ implements LocaleServiceProviderPool.LocalizedObjectGetter<TimeZoneNameProvider,
146+ String[]>{
147+ private static final TimeZoneNameGetter INSTANCE =
148+ new TimeZoneNameGetter();
149+
150+ public String[] getObject(TimeZoneNameProvider timeZoneNameProvider,
151+ Locale locale,
152+ String requestID,
153+ Object... params) {
154+ assert params.length == 0;
155+ String[] names = null;
156+ String queryID = requestID;
157+
158+ if (queryID.equals("GMT")) {
159+ names = buildZoneStrings(timeZoneNameProvider, locale, queryID);
160+ } else {
161+ Map<String, String> aliases = ZoneInfo.getAliasTable();
162+
163+ if (aliases != null) {
164+ // Check whether this id is an alias, if so,
165+ // look for the standard id.
166+ if (aliases.containsKey(queryID)) {
167+ String prevID = queryID;
168+ while ((queryID = aliases.get(queryID)) != null) {
169+ prevID = queryID;
170+ }
171+ queryID = prevID;
172+ }
173+
174+ names = buildZoneStrings(timeZoneNameProvider, locale, queryID);
175+
176+ if (names == null) {
177+ // There may be a case that a standard id has become an
178+ // alias. so, check the aliases backward.
179+ names = examineAliases(timeZoneNameProvider, locale,
180+ queryID, aliases, aliases.entrySet());
181+ }
182+ }
183+ }
184+
185+ if (names != null) {
186+ names[0] = requestID;
187+ }
188+
189+ return names;
190+ }
191+
192+ private static String[] examineAliases(TimeZoneNameProvider tznp, Locale locale,
193+ String id,
194+ Map<String, String> aliases,
195+ Set<Map.Entry<String, String>> aliasesSet) {
196+ if (aliases.containsValue(id)) {
197+ for (Map.Entry<String, String> entry : aliasesSet) {
198+ if (entry.getValue().equals(id)) {
199+ String alias = entry.getKey();
200+ String[] names = buildZoneStrings(tznp, locale, alias);
201+ if (names != null) {
202+ return names;
203+ } else {
204+ names = examineAliases(tznp, locale, alias, aliases, aliasesSet);
205+ if (names != null) {
206+ return names;
207+ }
208+ }
209+ }
210+ }
211+ }
212+
213+ return null;
214+ }
215+
216+ private static String[] buildZoneStrings(TimeZoneNameProvider tznp,
217+ Locale locale, String id) {
218+ String[] names = new String[5];
219+
220+ for (int i = 1; i <= 4; i ++) {
221+ names[i] = tznp.getDisplayName(id, i>=3, i%2, locale);
222+ if (i >= 3 && names[i] == null) {
223+ names[i] = names[i-2];
224+ }
225+ }
226+
227+ if (names[1] == null) {
228+ // this id seems not localized by this provider
229+ names = null;
230+ }
231+
232+ return names;
233+ }
234+ }
235+}