1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application;
20
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Locale;
27 import java.util.Set;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.concurrent.ConcurrentMap;
30
31
32
33
34
35
36
37
38
39
40
41
42
43 class _LocaleUtils
44 {
45
46
47 private static final ConcurrentMap<String, List<Locale>> LANGUAGES_BY_COUNTRY =
48 new ConcurrentHashMap<String, List<Locale>>();
49
50
51 private static final ConcurrentMap<String, List<Locale>> COUNTRIES_BY_LANGUAGE =
52 new ConcurrentHashMap<String, List<Locale>>();
53
54
55
56
57
58
59
60
61 public _LocaleUtils()
62 {
63 super();
64 }
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 public static Locale toLocale(String str)
96 {
97 if (str == null)
98 {
99 return null;
100 }
101 int len = str.length();
102 if (len != 2 && len != 5 && len < 7)
103 {
104 throw new IllegalArgumentException("Invalid locale format: " + str);
105 }
106 char ch0 = str.charAt(0);
107 char ch1 = str.charAt(1);
108 if (ch0 < 'a' || ch0 > 'z' || ch1 < 'a' || ch1 > 'z')
109 {
110 throw new IllegalArgumentException("Invalid locale format: " + str);
111 }
112 if (len == 2)
113 {
114 return new Locale(str, "");
115 }
116 else
117 {
118 if (str.charAt(2) != '_')
119 {
120 throw new IllegalArgumentException("Invalid locale format: " + str);
121 }
122 char ch3 = str.charAt(3);
123 if (ch3 == '_')
124 {
125 return new Locale(str.substring(0, 2), "", str.substring(4));
126 }
127 char ch4 = str.charAt(4);
128 if (ch3 < 'A' || ch3 > 'Z' || ch4 < 'A' || ch4 > 'Z')
129 {
130 throw new IllegalArgumentException("Invalid locale format: " + str);
131 }
132 if (len == 5)
133 {
134 return new Locale(str.substring(0, 2), str.substring(3, 5));
135 }
136 else
137 {
138 if (str.charAt(5) != '_')
139 {
140 throw new IllegalArgumentException("Invalid locale format: " + str);
141 }
142 return new Locale(str.substring(0, 2), str.substring(3, 5), str.substring(6));
143 }
144 }
145 }
146
147
148
149
150
151
152
153 public static Locale deriveLocale(String str)
154 {
155 if (str == null)
156 {
157 return null;
158 }
159 int len = str.length();
160 if (len != 2 && len != 5 && len < 7)
161 {
162 return null;
163 }
164 char ch0 = str.charAt(0);
165 char ch1 = str.charAt(1);
166 if (ch0 < 'a' || ch0 > 'z' || ch1 < 'a' || ch1 > 'z')
167 {
168 return null;
169 }
170 if (len == 2)
171 {
172 return new Locale(str, "");
173 }
174 else
175 {
176 if (str.charAt(2) != '_')
177 {
178 return null;
179 }
180 char ch3 = str.charAt(3);
181 if (ch3 == '_')
182 {
183 return new Locale(str.substring(0, 2), "", str.substring(4));
184 }
185 char ch4 = str.charAt(4);
186 if (ch3 < 'A' || ch3 > 'Z' || ch4 < 'A' || ch4 > 'Z')
187 {
188 return null;
189 }
190 if (len == 5)
191 {
192 return new Locale(str.substring(0, 2), str.substring(3, 5));
193 }
194 else
195 {
196 if (str.charAt(5) != '_')
197 {
198 return null;
199 }
200 return new Locale(str.substring(0, 2), str.substring(3, 5), str.substring(6));
201 }
202 }
203 }
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 public static List<Locale> localeLookupList(Locale locale)
220 {
221 return localeLookupList(locale, locale);
222 }
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243 public static List<Locale> localeLookupList(Locale locale, Locale defaultLocale)
244 {
245 List<Locale> list = new ArrayList<Locale>(4);
246 if (locale != null)
247 {
248 list.add(locale);
249 if (locale.getVariant().length() > 0)
250 {
251 list.add(new Locale(locale.getLanguage(), locale.getCountry()));
252 }
253 if (locale.getCountry().length() > 0)
254 {
255 list.add(new Locale(locale.getLanguage(), ""));
256 }
257 if (!list.contains(defaultLocale))
258 {
259 list.add(defaultLocale);
260 }
261 }
262 return Collections.unmodifiableList(list);
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276 public static List<Locale> availableLocaleList()
277 {
278 return SyncAvoid.AVAILABLE_LOCALE_LIST;
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292 public static Set<Locale> availableLocaleSet()
293 {
294 return SyncAvoid.AVAILABLE_LOCALE_SET;
295 }
296
297
298
299
300
301
302
303
304
305 public static boolean isAvailableLocale(Locale locale)
306 {
307 return availableLocaleList().contains(locale);
308 }
309
310
311
312
313
314
315
316
317
318
319
320
321 public static List<Locale> languagesByCountry(String countryCode)
322 {
323 if (countryCode == null)
324 {
325 return Collections.emptyList();
326 }
327 List<Locale> langs = LANGUAGES_BY_COUNTRY.get(countryCode);
328 if (langs == null)
329 {
330 langs = new ArrayList<Locale>();
331 List<Locale> locales = availableLocaleList();
332 for (int i = 0; i < locales.size(); i++)
333 {
334 Locale locale = locales.get(i);
335 if (countryCode.equals(locale.getCountry()) &&
336 locale.getVariant().length() == 0)
337 {
338 langs.add(locale);
339 }
340 }
341 langs = Collections.unmodifiableList(langs);
342 LANGUAGES_BY_COUNTRY.putIfAbsent(countryCode, langs);
343 langs = LANGUAGES_BY_COUNTRY.get(countryCode);
344 }
345 return langs;
346 }
347
348
349
350
351
352
353
354
355
356
357
358
359 public static List<Locale> countriesByLanguage(String languageCode)
360 {
361 if (languageCode == null)
362 {
363 return Collections.emptyList();
364 }
365 List<Locale> countries = COUNTRIES_BY_LANGUAGE.get(languageCode);
366 if (countries == null)
367 {
368 countries = new ArrayList<Locale>();
369 List<Locale> locales = availableLocaleList();
370 for (int i = 0; i < locales.size(); i++)
371 {
372 Locale locale = locales.get(i);
373 if (languageCode.equals(locale.getLanguage()) &&
374 locale.getCountry().length() != 0 &&
375 locale.getVariant().length() == 0)
376 {
377 countries.add(locale);
378 }
379 }
380 countries = Collections.unmodifiableList(countries);
381 COUNTRIES_BY_LANGUAGE.putIfAbsent(languageCode, countries);
382 countries = COUNTRIES_BY_LANGUAGE.get(languageCode);
383 }
384 return countries;
385 }
386
387
388
389 static class SyncAvoid
390 {
391
392 private static final List<Locale> AVAILABLE_LOCALE_LIST;
393
394 private static final Set<Locale> AVAILABLE_LOCALE_SET;
395
396 static
397 {
398 List<Locale> list = new ArrayList<Locale>(Arrays.asList(Locale.getAvailableLocales()));
399 AVAILABLE_LOCALE_LIST = Collections.unmodifiableList(list);
400 AVAILABLE_LOCALE_SET = Collections.unmodifiableSet(new HashSet<Locale>(availableLocaleList()));
401 }
402 }
403
404 }