1 /*
2 * Copyright (c) 1996, 2011, 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 /*
27 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29 *
30 * The original version of this source code and documentation
31 * is copyrighted and owned by Taligent, Inc., a wholly-owned
32 * subsidiary of IBM. These materials are provided under terms
33 * of a License Agreement between Taligent and Sun. This technology
34 * is protected by multiple US and International patents.
35 *
36 * This notice and attribution to Taligent may not be removed.
37 * Taligent is a registered trademark of Taligent, Inc.
38 *
39 */
40
41 package sun.util.resources;
42
43 import java.io.File;
44 import java.security.AccessController;
45 import java.security.PrivilegedAction;
46 import java.util.Iterator;
47 import java.util.List;
48 import java.util.Locale;
49 import java.util.ResourceBundle;
50 import java.util.StringTokenizer;
51
52 import sun.util.LocaleDataMetaInfo;
53
54 /**
55 * Provides information about and access to resource bundles in the
56 * sun.text.resources and sun.util.resources package.
57 *
58 * @author Asmus Freytag
59 * @author Mark Davis
60 */
61
62 public class LocaleData {
63
64 private static final String localeDataJarName = "localedata.jar";
65
66 /**
67 * Lazy load available locales.
68 */
69 private static class AvailableLocales {
70 static final Locale[] localeList = createLocaleList();
71 }
72
73 /**
74 * Returns a list of the installed locales. Currently, this simply returns
75 * the list of locales for which a sun.text.resources.FormatData bundle
76 * exists. This bundle family happens to be the one with the broadest
77 * locale coverage in the JRE.
78 */
79 public static Locale[] getAvailableLocales() {
80 return AvailableLocales.localeList.clone();
81 }
82
83 /**
84 * Gets a calendar data resource bundle, using privileges
85 * to allow accessing a sun.* package.
86 */
87 public static ResourceBundle getCalendarData(Locale locale) {
88 return getBundle("sun.util.resources.CalendarData", locale);
89 }
90
91 /**
92 * Gets a currency names resource bundle, using privileges
93 * to allow accessing a sun.* package.
94 */
95 public static OpenListResourceBundle getCurrencyNames(Locale locale) {
96 return (OpenListResourceBundle)getBundle("sun.util.resources.CurrencyNames", locale);
97 }
98
99 /**
100 * Gets a locale names resource bundle, using privileges
101 * to allow accessing a sun.* package.
102 */
103 public static OpenListResourceBundle getLocaleNames(Locale locale) {
104 return (OpenListResourceBundle)getBundle("sun.util.resources.LocaleNames", locale);
105 }
106
107 /**
108 * Gets a time zone names resource bundle, using privileges
109 * to allow accessing a sun.* package.
110 */
111 public static OpenListResourceBundle getTimeZoneNames(Locale locale) {
112 return (OpenListResourceBundle)getBundle("sun.util.resources.TimeZoneNames", locale);
113 }
114
115 /**
116 * Gets a collation data resource bundle, using privileges
117 * to allow accessing a sun.* package.
118 */
119 public static ResourceBundle getCollationData(Locale locale) {
120 return getBundle("sun.text.resources.CollationData", locale);
121 }
122
123 /**
124 * Gets a date format data resource bundle, using privileges
125 * to allow accessing a sun.* package.
126 */
127 public static ResourceBundle getDateFormatData(Locale locale) {
128 return getBundle("sun.text.resources.FormatData", locale);
129 }
130
131 /**
132 * Gets a number format data resource bundle, using privileges
133 * to allow accessing a sun.* package.
134 */
135 public static ResourceBundle getNumberFormatData(Locale locale) {
136 return getBundle("sun.text.resources.FormatData", locale);
137 }
138
139 private static ResourceBundle getBundle(final String baseName, final Locale locale) {
140 return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
141 public ResourceBundle run() {
142 return ResourceBundle.
143 getBundle(baseName, locale,
144 LocaleDataResourceBundleControl.getRBControlInstance());
145 }
146 });
147 }
148
149 static class LocaleDataResourceBundleControl extends ResourceBundle.Control {
150 /* Singlton instance of ResourceBundle.Control. */
151 private static LocaleDataResourceBundleControl rbControlInstance =
152 new LocaleDataResourceBundleControl();
153
154 public static LocaleDataResourceBundleControl getRBControlInstance() {
155 return rbControlInstance;
156 }
157
158 /*
159 * This method overrides the default implementation to search
160 * from a prebaked locale string list to determin the candidate
161 * locale list.
162 *
163 * @param baseName the resource bundle base name.
164 * locale the requested locale for the resource bundle.
165 * @returns a list of candidate locales to search from.
166 * @exception NullPointerException if baseName or locale is null.
167 */
168 @Override
169 public List<Locale> getCandidateLocales(String baseName, Locale locale) {
170 List<Locale> candidates = super.getCandidateLocales(baseName, locale);
171 /* Get the locale string list from LocaleDataMetaInfo class. */
172 String localeString = LocaleDataMetaInfo.getSupportedLocaleString(baseName);
173
174 if (localeString.length() == 0) {
175 return candidates;
176 }
177
178 for (Iterator<Locale> l = candidates.iterator(); l.hasNext(); ) {
179 Locale loc = l.next();
180 String lstr = null;
181 if (loc.getScript().length() > 0) {
182 lstr = loc.toLanguageTag().replace('-', '_');
183 } else {
184 lstr = loc.toString();
185 int idx = lstr.indexOf("_#");
186 if (idx >= 0) {
187 lstr = lstr.substring(0, idx);
188 }
189 }
190 /* Every locale string in the locale string list returned from
191 the above getSupportedLocaleString is enclosed
192 within two white spaces so that we could check some locale
193 such as "en".
194 */
195 if (lstr.length() != 0 && localeString.indexOf(" " + lstr + " ") == -1) {
196 l.remove();
197 }
198 }
199 return candidates;
200 }
201
202 /*
203 * Overrides "getFallbackLocale" to return null so
204 * that the fallback locale will be null.
205 * @param baseName the resource bundle base name.
206 * locale the requested locale for the resource bundle.
207 * @return null for the fallback locale.
208 * @exception NullPointerException if baseName or locale is null.
209 */
210 @Override
211 public Locale getFallbackLocale(String baseName, Locale locale) {
212 if (baseName == null || locale == null) {
213 throw new NullPointerException();
214 }
215 return null;
216 }
217 }
218
219 /*
220 * Returns true if the non European resources jar file exists in jre
221 * extension directory.
222 * @returns true if the jar file is there. Otherwise, returns false.
223 */
224 private static boolean isNonEuroLangSupported() {
225 final String sep = File.separator;
226 String localeDataJar =
227 java.security.AccessController.doPrivileged(
228 new sun.security.action.GetPropertyAction("java.home")) +
229 sep + "lib" + sep + "ext" + sep + localeDataJarName;
230
231 /* Peek at the installed extension directory to see if
232 localedata.jar is installed or not.
233 */
234 final File f = new File(localeDataJar);
235 boolean isNonEuroResJarExist =
236 AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
237 public Boolean run() {
238 return Boolean.valueOf(f.exists());
239 }
240 }).booleanValue();
241
242 return isNonEuroResJarExist;
243 }
244
245 /*
246 * This method gets the locale string list from LocaleDataMetaInfo class and
247 * then contructs the Locale array based on the locale string returned above.
248 * @returns the Locale array for the supported locale of JRE.
249 *
250 */
251 private static Locale[] createLocaleList() {
252 String supportedLocaleString = LocaleDataMetaInfo.
253 getSupportedLocaleString("sun.text.resources.FormatData");
254
255 if (supportedLocaleString.length() == 0) {
256 return null;
257 }
258
259 /* Look for "|" and construct a new locale string list. */
260 int barIndex = supportedLocaleString.indexOf("|");
261 StringTokenizer localeStringTokenizer = null;
262 if (isNonEuroLangSupported()) {
263 localeStringTokenizer = new
264 StringTokenizer(supportedLocaleString.substring(0, barIndex) +
265 supportedLocaleString.substring(barIndex + 1));
266 } else {
267 localeStringTokenizer = new
268 StringTokenizer(supportedLocaleString.substring(0, barIndex));
269 }
270
271 Locale[] locales = new Locale[localeStringTokenizer.countTokens()];
272 for (int i = 0; i < locales.length; i++) {
273 String currentToken = localeStringTokenizer.nextToken().replace('_','-');
274 if (currentToken.equals("ja-JP-JP")) {
275 currentToken = "ja-JP-u-ca-japanese-x-lvariant-JP";
276 } else if (currentToken.equals("th-TH-TH")) {
277 currentToken = "th-TH-u-nu-thai-x-lvariant-TH";
278 } else if (currentToken.equals("no-NO-NY")) {
279 currentToken = "no-NO-x-lvariant-NY";
280 }
281 locales[i] = Locale.forLanguageTag(currentToken);
282 }
283 return locales;
284 }
285
286 }
|
1 /*
2 * Copyright (c) 1996, 2012, 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 /*
27 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29 *
30 * The original version of this source code and documentation
31 * is copyrighted and owned by Taligent, Inc., a wholly-owned
32 * subsidiary of IBM. These materials are provided under terms
33 * of a License Agreement between Taligent and Sun. This technology
34 * is protected by multiple US and International patents.
35 *
36 * This notice and attribution to Taligent may not be removed.
37 * Taligent is a registered trademark of Taligent, Inc.
38 *
39 */
40
41 package sun.util.resources;
42
43 import java.security.AccessController;
44 import java.security.PrivilegedAction;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.Locale;
48 import java.util.ResourceBundle;
49 import sun.util.locale.provider.LocaleProviderAdapter;
50 import static sun.util.locale.provider.LocaleProviderAdapter.Type.JRE;
51 import sun.util.locale.provider.LocaleDataMetaInfo;
52
53 /**
54 * Provides information about and access to resource bundles in the
55 * sun.text.resources and sun.util.resources packages or in their corresponding
56 * packages for CLDR.
57 *
58 * @author Asmus Freytag
59 * @author Mark Davis
60 */
61
62 public class LocaleData {
63 private final LocaleProviderAdapter.Type type;
64
65 public LocaleData(LocaleProviderAdapter.Type type) {
66 this.type = type;
67 }
68
69 /**
70 * Gets a calendar data resource bundle, using privileges
71 * to allow accessing a sun.* package.
72 */
73 public ResourceBundle getCalendarData(Locale locale) {
74 return getBundle(type.getUtilResourcesPackage() + ".CalendarData", locale);
75 }
76
77 /**
78 * Gets a currency names resource bundle, using privileges
79 * to allow accessing a sun.* package.
80 */
81 public OpenListResourceBundle getCurrencyNames(Locale locale) {
82 return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".CurrencyNames", locale);
83 }
84
85 /**
86 * Gets a locale names resource bundle, using privileges
87 * to allow accessing a sun.* package.
88 */
89 public OpenListResourceBundle getLocaleNames(Locale locale) {
90 return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".LocaleNames", locale);
91 }
92
93 /**
94 * Gets a time zone names resource bundle, using privileges
95 * to allow accessing a sun.* package.
96 */
97 public OpenListResourceBundle getTimeZoneNames(Locale locale) {
98 return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".TimeZoneNames", locale);
99 }
100
101 /**
102 * Gets a collation data resource bundle, using privileges
103 * to allow accessing a sun.* package.
104 */
105 public ResourceBundle getCollationData(Locale locale) {
106 return getBundle(type.getTextResourcesPackage() + ".CollationData", locale);
107 }
108
109 /**
110 * Gets a date format data resource bundle, using privileges
111 * to allow accessing a sun.* package.
112 */
113 public ResourceBundle getDateFormatData(Locale locale) {
114 return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
115 }
116
117 /**
118 * Gets a number format data resource bundle, using privileges
119 * to allow accessing a sun.* package.
120 */
121 public ResourceBundle getNumberFormatData(Locale locale) {
122 return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
123 }
124
125 public static ResourceBundle getBundle(final String baseName, final Locale locale) {
126 return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
127 @Override
128 public ResourceBundle run() {
129 return ResourceBundle.
130 getBundle(baseName, locale,
131 LocaleDataResourceBundleControl.getRBControlInstance());
132 }
133 });
134 }
135
136 private static class LocaleDataResourceBundleControl extends ResourceBundle.Control {
137 /* Singlton instance of ResourceBundle.Control. */
138 private static LocaleDataResourceBundleControl rbControlInstance =
139 new LocaleDataResourceBundleControl();
140
141 public static LocaleDataResourceBundleControl getRBControlInstance() {
142 return rbControlInstance;
143 }
144
145 /*
146 * This method overrides the default implementation to search
147 * from a prebaked locale string list to determin the candidate
148 * locale list.
149 *
150 * @param baseName the resource bundle base name.
151 * locale the requested locale for the resource bundle.
152 * @returns a list of candidate locales to search from.
153 * @exception NullPointerException if baseName or locale is null.
154 */
155 @Override
156 public List<Locale> getCandidateLocales(String baseName, Locale locale) {
157 List<Locale> candidates = super.getCandidateLocales(baseName, locale);
158 /* Get the locale string list from LocaleDataMetaInfo class. */
159 String localeString = LocaleDataMetaInfo.getSupportedLocaleString(baseName);
160
161 if (localeString == null || localeString.length() == 0) {
162 return candidates;
163 }
164
165 for (Iterator<Locale> l = candidates.iterator(); l.hasNext(); ) {
166 Locale loc = l.next();
167 String lstr;
168 if (loc.getScript().length() > 0) {
169 lstr = loc.toLanguageTag().replace('-', '_');
170 } else {
171 lstr = loc.toString();
172 int idx = lstr.indexOf("_#");
173 if (idx >= 0) {
174 lstr = lstr.substring(0, idx);
175 }
176 }
177 /* Every locale string in the locale string list returned from
178 the above getSupportedLocaleString is enclosed
179 within two white spaces so that we could check some locale
180 such as "en".
181 */
182 if (lstr.length() != 0 && localeString.indexOf(" " + lstr + " ") == -1) {
183 l.remove();
184 }
185 }
186 return candidates;
187 }
188
189 /*
190 * Overrides "getFallbackLocale" to return null so
191 * that the fallback locale will be null.
192 * @param baseName the resource bundle base name.
193 * locale the requested locale for the resource bundle.
194 * @return null for the fallback locale.
195 * @exception NullPointerException if baseName or locale is null.
196 */
197 @Override
198 public Locale getFallbackLocale(String baseName, Locale locale) {
199 if (baseName == null || locale == null) {
200 throw new NullPointerException();
201 }
202 return null;
203 }
204
205 private static final String CLDR = ".cldr";
206
207 /**
208 * Changes baseName to its per-language package name and
209 * calls the super class implementation. For example,
210 * if the baseName is "sun.text.resources.FormatData" and locale is ja_JP,
211 * the baseName is changed to "sun.text.resources.ja.FormatData". If
212 * baseName contains "cldr", such as "sun.text.resources.cldr.FormatData",
213 * the name is changed to "sun.text.resources.cldr.jp.FormatData".
214 */
215 @Override
216 public String toBundleName(String baseName, Locale locale) {
217 String newBaseName = baseName;
218 String lang = locale.getLanguage();
219 if (lang.length() > 0) {
220 if (baseName.startsWith(JRE.getUtilResourcesPackage())
221 || baseName.startsWith(JRE.getTextResourcesPackage())) {
222 // Assume the lengths are the same.
223 assert JRE.getUtilResourcesPackage().length()
224 == JRE.getTextResourcesPackage().length();
225 int index = JRE.getUtilResourcesPackage().length();
226 if (baseName.indexOf(CLDR, index) > 0) {
227 index += CLDR.length();
228 }
229 newBaseName = baseName.substring(0, index + 1) + lang
230 + baseName.substring(index);
231 }
232 }
233 return super.toBundleName(newBaseName, locale);
234 }
235
236 }
237 }
|