1 /*
2 * Copyright (c) 2012, 2013, 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
24 */
25 package sun.util.locale.provider;
26
27 import static java.util.Calendar.*;
28 import java.util.Comparator;
29 import java.util.Locale;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.TreeMap;
33 import java.util.spi.CalendarNameProvider;
34
35 /**
36 * Concrete implementation of the {@link java.util.spi.CalendarDataProvider
37 * CalendarDataProvider} class for the JRE LocaleProviderAdapter.
38 *
39 * @author Masayoshi Okutsu
40 * @author Naoto Sato
41 */
42 public class CalendarNameProviderImpl extends CalendarNameProvider implements AvailableLanguageTags {
43 private final LocaleProviderAdapter.Type type;
44 private final Set<String> langtags;
45
46 public CalendarNameProviderImpl(LocaleProviderAdapter.Type type, Set<String> langtags) {
47 this.type = type;
48 this.langtags = langtags;
49 }
50
51 @Override
52 public String getDisplayName(String calendarType, int field, int value, int style, Locale locale) {
53 return getDisplayNameImpl(calendarType, field, value, style, locale, false);
54 }
55
56 public String getJavaTimeDisplayName(String calendarType, int field, int value, int style, Locale locale) {
57 return getDisplayNameImpl(calendarType, field, value, style, locale, true);
58 }
59
60 public String getDisplayNameImpl(String calendarType, int field, int value, int style, Locale locale, boolean javatime) {
61 String name = null;
62 String key = getResourceKey(calendarType, field, style, javatime);
63 if (key != null) {
64 LocaleResources lr = LocaleProviderAdapter.forType(type).getLocaleResources(locale);
65 String[] strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
66 if (strings != null && strings.length > 0) {
67 if (field == DAY_OF_WEEK || field == YEAR) {
68 --value;
69 }
70 if (value < 0 || value >= strings.length) {
71 return null;
72 }
73 name = strings[value];
74 // If name is empty in standalone, try its `format' style.
75 if (name.length() == 0
76 && (style == SHORT_STANDALONE || style == LONG_STANDALONE
77 || style == NARROW_STANDALONE)) {
78 name = getDisplayName(calendarType, field, value,
79 getBaseStyle(style),
80 locale);
81 }
82 }
83 }
84 return name;
85 }
86
87 private static int[] REST_OF_STYLES = {
88 SHORT_STANDALONE, LONG_FORMAT, LONG_STANDALONE,
89 NARROW_FORMAT, NARROW_STANDALONE
90 };
91
92 @Override
93 public Map<String, Integer> getDisplayNames(String calendarType, int field, int style, Locale locale) {
94 Map<String, Integer> names;
95 if (style == ALL_STYLES) {
96 names = getDisplayNamesImpl(calendarType, field, SHORT_FORMAT, locale, false);
97 for (int st : REST_OF_STYLES) {
98 names.putAll(getDisplayNamesImpl(calendarType, field, st, locale, false));
99 }
100 } else {
101 // specific style
102 names = getDisplayNamesImpl(calendarType, field, style, locale, false);
103 }
104 return names.isEmpty() ? null : names;
105 }
106
107 // NOTE: This method should be used ONLY BY JSR 310 classes.
148
149 /**
150 * Comparator implementation for TreeMap which iterates keys from longest
151 * to shortest.
152 */
153 private static class LengthBasedComparator implements Comparator<String> {
154 private static final LengthBasedComparator INSTANCE = new LengthBasedComparator();
155
156 private LengthBasedComparator() {
157 }
158
159 @Override
160 public int compare(String o1, String o2) {
161 int n = o2.length() - o1.length();
162 return (n == 0) ? o1.compareTo(o2) : n;
163 }
164 }
165
166 @Override
167 public Locale[] getAvailableLocales() {
168 return LocaleProviderAdapter.toLocaleArray(langtags);
169 }
170
171 @Override
172 public boolean isSupportedLocale(Locale locale) {
173 if (Locale.ROOT.equals(locale)) {
174 return true;
175 }
176 String calendarType = null;
177 if (locale.hasExtensions()) {
178 calendarType = locale.getUnicodeLocaleType("ca");
179 locale = locale.stripExtensions();
180 }
181
182 if (calendarType != null) {
183 switch (calendarType) {
184 case "buddhist":
185 case "japanese":
186 case "gregory":
187 case "islamic":
188 case "roc":
189 break;
190 default:
191 // Unknown calendar type
192 return false;
193 }
194 }
195 if (langtags.contains(locale.toLanguageTag())) {
196 return true;
197 }
198 if (type == LocaleProviderAdapter.Type.JRE) {
199 String oldname = locale.toString().replace('_', '-');
200 return langtags.contains(oldname);
201 }
202 return false;
203 }
204
205 @Override
206 public Set<String> getAvailableLanguageTags() {
207 return langtags;
208 }
209
210 private boolean hasDuplicates(String[] strings) {
211 int len = strings.length;
212 for (int i = 0; i < len - 1; i++) {
213 String a = strings[i];
214 if (a != null) {
215 for (int j = i + 1; j < len; j++) {
216 if (a.equals(strings[j])) {
217 return true;
218 }
219 }
220 }
221 }
222 return false;
223 }
224
225 private String getResourceKey(String type, int field, int style, boolean javatime) {
226 int baseStyle = getBaseStyle(style);
227 boolean isStandalone = (style != baseStyle);
|
1 /*
2 * Copyright (c) 2012, 2014, 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
24 */
25 package sun.util.locale.provider;
26
27 import static java.util.Calendar.*;
28 import java.util.Comparator;
29 import java.util.Locale;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.TreeMap;
33 import java.util.spi.CalendarNameProvider;
34
35 /**
36 * Concrete implementation of the {@link java.util.spi.CalendarDataProvider
37 * CalendarDataProvider} class for the JRE LocaleProviderAdapter.
38 *
39 * @author Masayoshi Okutsu
40 * @author Naoto Sato
41 */
42 public class CalendarNameProviderImpl extends CalendarNameProvider implements AvailableLanguageTags {
43 private final LocaleProviderAdapter.Type type;
44
45 public CalendarNameProviderImpl(LocaleProviderAdapter.Type type) {
46 this.type = type;
47 }
48
49 @Override
50 public String getDisplayName(String calendarType, int field, int value, int style, Locale locale) {
51 return getDisplayNameImpl(calendarType, field, value, style, locale, false);
52 }
53
54 public String getJavaTimeDisplayName(String calendarType, int field, int value, int style, Locale locale) {
55 return getDisplayNameImpl(calendarType, field, value, style, locale, true);
56 }
57
58 public String getDisplayNameImpl(String calendarType, int field, int value, int style, Locale locale, boolean javatime) {
59 String name = null;
60 String key = getResourceKey(calendarType, field, style, javatime);
61 if (key != null) {
62 LocaleResources lr = LocaleProviderAdapter.forType(type).getLocaleResources(locale);
63 String[] strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
64 if (strings != null && strings.length > 0) {
65 if (field == DAY_OF_WEEK || field == YEAR) {
66 --value;
67 }
68 if (value < 0 || value >= strings.length) {
69 return null;
70 }
71 name = strings[value];
72 // If name is empty in standalone, try its `format' style.
73 if (name.length() == 0
74 && (style == SHORT_STANDALONE || style == LONG_STANDALONE
75 || style == NARROW_STANDALONE)) {
76 name = getDisplayName(calendarType, field, value,
77 getBaseStyle(style),
78 locale);
79 }
80 }
81 }
82 return name;
83 }
84
85 private static final int[] REST_OF_STYLES = {
86 SHORT_STANDALONE, LONG_FORMAT, LONG_STANDALONE,
87 NARROW_FORMAT, NARROW_STANDALONE
88 };
89
90 @Override
91 public Map<String, Integer> getDisplayNames(String calendarType, int field, int style, Locale locale) {
92 Map<String, Integer> names;
93 if (style == ALL_STYLES) {
94 names = getDisplayNamesImpl(calendarType, field, SHORT_FORMAT, locale, false);
95 for (int st : REST_OF_STYLES) {
96 names.putAll(getDisplayNamesImpl(calendarType, field, st, locale, false));
97 }
98 } else {
99 // specific style
100 names = getDisplayNamesImpl(calendarType, field, style, locale, false);
101 }
102 return names.isEmpty() ? null : names;
103 }
104
105 // NOTE: This method should be used ONLY BY JSR 310 classes.
146
147 /**
148 * Comparator implementation for TreeMap which iterates keys from longest
149 * to shortest.
150 */
151 private static class LengthBasedComparator implements Comparator<String> {
152 private static final LengthBasedComparator INSTANCE = new LengthBasedComparator();
153
154 private LengthBasedComparator() {
155 }
156
157 @Override
158 public int compare(String o1, String o2) {
159 int n = o2.length() - o1.length();
160 return (n == 0) ? o1.compareTo(o2) : n;
161 }
162 }
163
164 @Override
165 public Locale[] getAvailableLocales() {
166 return LocaleProviderAdapter.toLocaleArray(DateFormatProviderImpl.getLangTags(type));
167 }
168
169 @Override
170 public boolean isSupportedLocale(Locale locale) {
171 if (Locale.ROOT.equals(locale)) {
172 return true;
173 }
174 String calendarType = null;
175 if (locale.hasExtensions()) {
176 calendarType = locale.getUnicodeLocaleType("ca");
177 locale = locale.stripExtensions();
178 }
179
180 if (calendarType != null) {
181 switch (calendarType) {
182 case "buddhist":
183 case "japanese":
184 case "gregory":
185 case "islamic":
186 case "roc":
187 break;
188 default:
189 // Unknown calendar type
190 return false;
191 }
192 }
193 if (DateFormatProviderImpl.getLangTags(type).contains(locale.toLanguageTag())) {
194 return true;
195 }
196 if (type == LocaleProviderAdapter.Type.JRE) {
197 String oldname = locale.toString().replace('_', '-');
198 return DateFormatProviderImpl.getLangTags(type).contains(oldname);
199 }
200 return false;
201 }
202
203 @Override
204 public Set<String> getAvailableLanguageTags() {
205 return DateFormatProviderImpl.getLangTags(type);
206 }
207
208 private boolean hasDuplicates(String[] strings) {
209 int len = strings.length;
210 for (int i = 0; i < len - 1; i++) {
211 String a = strings[i];
212 if (a != null) {
213 for (int j = i + 1; j < len; j++) {
214 if (a.equals(strings[j])) {
215 return true;
216 }
217 }
218 }
219 }
220 return false;
221 }
222
223 private String getResourceKey(String type, int field, int style, boolean javatime) {
224 int baseStyle = getBaseStyle(style);
225 boolean isStandalone = (style != baseStyle);
|