1 /*
2 * Copyright (c) 2012, 2015, 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
30 import java.text.spi.DateFormatProvider;
31 import java.text.spi.DateFormatSymbolsProvider;
32 import java.text.spi.DecimalFormatSymbolsProvider;
33 import java.text.spi.NumberFormatProvider;
34 import java.util.Collections;
35 import java.util.Calendar;
36 import java.util.HashSet;
37 import java.util.Locale;
38 import java.util.Map;
39 import java.util.ResourceBundle.Control;
40 import java.util.Set;
41 import java.util.TimeZone;
42 import java.util.concurrent.ConcurrentHashMap;
43 import java.util.concurrent.ConcurrentMap;
44 import java.util.concurrent.atomic.AtomicReferenceArray;
45 import java.util.spi.CalendarDataProvider;
46 import java.util.spi.CalendarNameProvider;
47 import java.util.spi.CurrencyNameProvider;
48 import java.util.spi.LocaleNameProvider;
49 import java.util.spi.TimeZoneNameProvider;
50 import sun.util.spi.CalendarProvider;
51
52 /**
53 * LocaleProviderAdapter implementation for the Mac OS X locale data
54 *
55 * @author Naoto Sato
56 */
57 public class HostLocaleProviderAdapterImpl {
58
59 // per supported locale instances
60 private static final ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> dateFormatPatternsMap =
61 new ConcurrentHashMap<>(2);
62 private static final ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> numberFormatPatternsMap =
63 new ConcurrentHashMap<>(2);
64 private static final ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> dateFormatSymbolsMap =
65 new ConcurrentHashMap<>(2);
66 private static final ConcurrentMap<Locale, SoftReference<DecimalFormatSymbols>> decimalFormatSymbolsMap =
67 new ConcurrentHashMap<>(2);
68
69 // locale categories
130 break;
131 case "japanese":
132 // Tweak for ja_JP_JP
133 if (tmp[0].equals("ja_JP")) {
134 return JRELocaleConstants.JA_JP_JP;
135 }
136
137 // fall through
138
139 default:
140 langTag += "-u-ca-" + calid;
141 break;
142 }
143 }
144 }
145 }
146
147 return Locale.forLanguageTag(langTag);
148 }
149
150 public static DateFormatProvider getDateFormatProvider() {
151 return new DateFormatProvider() {
152
153 @Override
154 public Locale[] getAvailableLocales() {
155 return getSupportedCalendarLocales();
156 }
157
158 @Override
159 public boolean isSupportedLocale(Locale locale) {
160 return isSupportedCalendarLocale(locale);
161 }
162
163 @Override
164 public DateFormat getDateInstance(int style, Locale locale) {
165 return new SimpleDateFormat(getDateTimePattern(style, -1, locale),
166 getCalendarLocale(locale));
167 }
168
169 @Override
|
1 /*
2 * Copyright (c) 2012, 2016, 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
30 import java.text.spi.DateFormatProvider;
31 import java.text.spi.DateFormatSymbolsProvider;
32 import java.text.spi.DecimalFormatSymbolsProvider;
33 import java.text.spi.NumberFormatProvider;
34 import java.util.Collections;
35 import java.util.Calendar;
36 import java.util.HashSet;
37 import java.util.Locale;
38 import java.util.Map;
39 import java.util.ResourceBundle.Control;
40 import java.util.Set;
41 import java.util.TimeZone;
42 import java.util.concurrent.ConcurrentHashMap;
43 import java.util.concurrent.ConcurrentMap;
44 import java.util.concurrent.atomic.AtomicReferenceArray;
45 import java.util.spi.CalendarDataProvider;
46 import java.util.spi.CalendarNameProvider;
47 import java.util.spi.CurrencyNameProvider;
48 import java.util.spi.LocaleNameProvider;
49 import java.util.spi.TimeZoneNameProvider;
50 import sun.text.spi.JavaTimeDateTimePatternProvider;
51 import sun.util.spi.CalendarProvider;
52
53 /**
54 * LocaleProviderAdapter implementation for the Mac OS X locale data
55 *
56 * @author Naoto Sato
57 */
58 public class HostLocaleProviderAdapterImpl {
59
60 // per supported locale instances
61 private static final ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> dateFormatPatternsMap =
62 new ConcurrentHashMap<>(2);
63 private static final ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> numberFormatPatternsMap =
64 new ConcurrentHashMap<>(2);
65 private static final ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> dateFormatSymbolsMap =
66 new ConcurrentHashMap<>(2);
67 private static final ConcurrentMap<Locale, SoftReference<DecimalFormatSymbols>> decimalFormatSymbolsMap =
68 new ConcurrentHashMap<>(2);
69
70 // locale categories
131 break;
132 case "japanese":
133 // Tweak for ja_JP_JP
134 if (tmp[0].equals("ja_JP")) {
135 return JRELocaleConstants.JA_JP_JP;
136 }
137
138 // fall through
139
140 default:
141 langTag += "-u-ca-" + calid;
142 break;
143 }
144 }
145 }
146 }
147
148 return Locale.forLanguageTag(langTag);
149 }
150
151 public static JavaTimeDateTimePatternProvider getJavaTimeDateTimePatternProvider() {
152 return new JavaTimeDateTimePatternProvider() {
153 @Override
154 public Locale[] getAvailableLocales() {
155 return getSupportedCalendarLocales();
156 }
157
158 @Override
159 public boolean isSupportedLocale(Locale locale) {
160 return isSupportedCalendarLocale(locale);
161 }
162
163 @Override
164 public String getJavaTimeDateTimePattern(int timeStyle, int dateStyle, String calType, Locale locale) {
165 return toJavaTimeDateTimePattern(calType, getDateTimePattern(dateStyle, timeStyle, locale));
166
167 }
168
169 private String getDateTimePattern(int dateStyle, int timeStyle, Locale locale) {
170 AtomicReferenceArray<String> dateFormatPatterns;
171 SoftReference<AtomicReferenceArray<String>> ref = dateFormatPatternsMap.get(locale);
172
173 if (ref == null || (dateFormatPatterns = ref.get()) == null) {
174 dateFormatPatterns = new AtomicReferenceArray<>(5 * 5);
175 ref = new SoftReference<>(dateFormatPatterns);
176 dateFormatPatternsMap.put(locale, ref);
177 }
178 int index = (dateStyle + 1) * 5 + timeStyle + 1;
179 String pattern = dateFormatPatterns.get(index);
180 if (pattern == null) {
181 String langTag = locale.toLanguageTag();
182 pattern = translateDateFormatLetters(getCalendarID(langTag),
183 getDateTimePatternNative(dateStyle, timeStyle, langTag));
184 if (!dateFormatPatterns.compareAndSet(index, null, pattern)) {
185 pattern = dateFormatPatterns.get(index);
186 }
187 }
188 return pattern;
189 }
190
191 /**
192 * This method will convert JRE Date/time Pattern String to JSR310
193 * type Date/Time Pattern
194 */
195 private String toJavaTimeDateTimePattern(String calendarType, String jrePattern) {
196 int length = jrePattern.length();
197 StringBuilder sb = new StringBuilder();
198 boolean inQuote = false;
199 int count = 0;
200 char lastLetter = 0;
201 for (int i = 0; i < length; i++) {
202 char c = jrePattern.charAt(i);
203 if (c == '\'') {
204 // '' is treated as a single quote regardless of being
205 // in a quoted section.
206 if ((i + 1) < length) {
207 char nextc = jrePattern.charAt(i + 1);
208 if (nextc == '\'') {
209 i++;
210 if (count != 0) {
211 convert(calendarType, lastLetter, count, sb);
212 lastLetter = 0;
213 count = 0;
214 }
215 sb.append("''");
216 continue;
217 }
218 }
219 if (!inQuote) {
220 if (count != 0) {
221 convert(calendarType, lastLetter, count, sb);
222 lastLetter = 0;
223 count = 0;
224 }
225 inQuote = true;
226 } else {
227 inQuote = false;
228 }
229 sb.append(c);
230 continue;
231 }
232 if (inQuote) {
233 sb.append(c);
234 continue;
235 }
236 if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) {
237 if (count != 0) {
238 convert(calendarType, lastLetter, count, sb);
239 lastLetter = 0;
240 count = 0;
241 }
242 sb.append(c);
243 continue;
244 }
245 if (lastLetter == 0 || lastLetter == c) {
246 lastLetter = c;
247 count++;
248 continue;
249 }
250 convert(calendarType, lastLetter, count, sb);
251 lastLetter = c;
252 count = 1;
253 }
254 if (inQuote) {
255 // should not come here.
256 // returning null so that FALLBACK provider will kick in.
257 return null;
258 }
259 if (count != 0) {
260 convert(calendarType, lastLetter, count, sb);
261 }
262 return sb.toString();
263 }
264
265 private void convert(String calendarType, char letter, int count, StringBuilder sb) {
266 switch (letter) {
267 case 'G':
268 if (calendarType.equals("japanese")) {
269 if (count >= 4) {
270 count = 1;
271 } else {
272 count = 5;
273 }
274 } else if (!calendarType.equals("iso8601")) {
275 // Gregorian calendar is iso8601 for java.time
276 // Adjust the number of 'G's
277 if (count >= 4) {
278 // JRE full -> JavaTime full
279 count = 4;
280 } else {
281 // JRE short -> JavaTime short
282 count = 1;
283 }
284 }
285 break;
286 case 'y':
287 if (calendarType.equals("japanese") && count >= 4) {
288 // JRE specific "gan-nen" support
289 count = 1;
290 }
291 break;
292 default:
293 // JSR 310 and CLDR define 5-letter patterns for narrow text.
294 if (count > 4) {
295 count = 4;
296 }
297 break;
298 }
299 appendN(letter, count, sb);
300 }
301
302 private void appendN(char c, int n, StringBuilder sb) {
303 for (int i = 0; i < n; i++) {
304 sb.append(c);
305 }
306 }
307 };
308 }
309
310 public static DateFormatProvider getDateFormatProvider() {
311 return new DateFormatProvider() {
312
313 @Override
314 public Locale[] getAvailableLocales() {
315 return getSupportedCalendarLocales();
316 }
317
318 @Override
319 public boolean isSupportedLocale(Locale locale) {
320 return isSupportedCalendarLocale(locale);
321 }
322
323 @Override
324 public DateFormat getDateInstance(int style, Locale locale) {
325 return new SimpleDateFormat(getDateTimePattern(style, -1, locale),
326 getCalendarLocale(locale));
327 }
328
329 @Override
|