42 import java.util.spi.LocaleNameProvider;
43 import java.util.spi.LocaleServiceProvider;
44 import java.util.spi.TimeZoneNameProvider;
45 import sun.util.cldr.CLDRLocaleProviderAdapter;
46 import sun.util.resources.LocaleData;
47
48 /**
49 * The LocaleProviderAdapter abstract class.
50 *
51 * @author Naoto Sato
52 * @author Masayoshi Okutsu
53 */
54 public abstract class LocaleProviderAdapter {
55 /**
56 * Adapter type.
57 */
58 public static enum Type {
59 JRE("sun.util.resources", "sun.text.resources"),
60 CLDR("sun.util.resources.cldr", "sun.text.resources.cldr"),
61 SPI,
62 HOST;
63
64 private final String UTIL_RESOURCES_PACKAGE;
65 private final String TEXT_RESOURCES_PACKAGE;
66
67 private Type() {
68 this(null, null);
69 }
70
71 private Type(String util, String text) {
72 UTIL_RESOURCES_PACKAGE = util;
73 TEXT_RESOURCES_PACKAGE = text;
74 }
75
76 public String getUtilResourcesPackage() {
77 return UTIL_RESOURCES_PACKAGE;
78 }
79
80 public String getTextResourcesPackage() {
81 return TEXT_RESOURCES_PACKAGE;
82 }
94 /**
95 * JRE Locale Data Adapter instance
96 */
97 private static LocaleProviderAdapter jreLocaleProviderAdapter = new JRELocaleProviderAdapter();
98
99 /**
100 * SPI Locale Data Adapter instance
101 */
102 private static LocaleProviderAdapter spiLocaleProviderAdapter = new SPILocaleProviderAdapter();
103
104 /**
105 * CLDR Locale Data Adapter instance, if any.
106 */
107 private static LocaleProviderAdapter cldrLocaleProviderAdapter = null;
108
109 /**
110 * HOST Locale Data Adapter instance, if any.
111 */
112 private static LocaleProviderAdapter hostLocaleProviderAdapter = null;
113
114 static {
115 String order = AccessController.doPrivileged(
116 new sun.security.action.GetPropertyAction("java.locale.providers"));
117 // Override adapterPreference with the properties one
118 if (order != null && order.length() != 0) {
119 String[] types = order.split(",");
120 List<Type> typeList = new ArrayList<>();
121 for (String type : types) {
122 try {
123 Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT));
124
125 // load adapter if necessary
126 switch (aType) {
127 case CLDR:
128 cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
129 break;
130 case HOST:
131 hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
132 break;
133 }
134 typeList.add(aType);
135 } catch (// could be caused by the user specifying wrong
136 // provider name or format in the system property
137 IllegalArgumentException |
138 UnsupportedOperationException e) {
139 LocaleServiceProviderPool.config(LocaleProviderAdapter.class, e.toString());
140 }
141 }
142
143 if (!typeList.contains(Type.JRE)) {
144 // Append JRE as the last resort.
145 typeList.add(Type.JRE);
146 }
147 adapterPreference = typeList.toArray(new Type[0]);
148 }
149 }
150
151
152 /**
153 * Returns the singleton instance for each adapter type
154 */
155 public static LocaleProviderAdapter forType(Type type) {
156 switch (type) {
157 case JRE:
158 return jreLocaleProviderAdapter;
159 case CLDR:
160 return cldrLocaleProviderAdapter;
161 case SPI:
162 return spiLocaleProviderAdapter;
163 case HOST:
164 return hostLocaleProviderAdapter;
165 default:
166 throw new InternalError("unknown locale data adapter type");
167 }
168 }
169
170 public static LocaleProviderAdapter forJRE() {
171 return jreLocaleProviderAdapter;
172 }
173
174 public static LocaleProviderAdapter getResourceBundleBased() {
175 for (Type type : getAdapterPreference()) {
176 if (type == Type.JRE || type == Type.CLDR) {
177 return forType(type);
178 }
179 }
180 // Shouldn't happen.
181 throw new InternalError();
182 }
183 /**
184 * Returns the preference order of LocaleProviderAdapter.Type
185 */
186 public static Type[] getAdapterPreference() {
187 return adapterPreference;
188 }
189
190 /**
191 * Returns a LocaleProviderAdapter for the given locale service provider that
192 * best matches the given locale. This method returns the LocaleProviderAdapter
193 * for JRE if none is found for the given locale.
194 *
195 * @param providerClass the class for the locale service provider
196 * @param locale the desired locale.
201 // Fast look-up for the given locale
202 LocaleProviderAdapter adapter = findAdapter(providerClass, locale);
203 if (adapter != null) {
204 return adapter;
205 }
206
207 // Try finding an adapter in the normal candidate locales path of the given locale.
208 List<Locale> lookupLocales = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT)
209 .getCandidateLocales("", locale);
210 for (Locale loc : lookupLocales) {
211 if (loc.equals(locale)) {
212 // We've already done with this loc.
213 continue;
214 }
215 adapter = findAdapter(providerClass, loc);
216 if (adapter != null) {
217 return adapter;
218 }
219 }
220
221 // returns the adapter for JRE as the last resort
222 return jreLocaleProviderAdapter;
223 }
224
225 private static LocaleProviderAdapter findAdapter(Class<? extends LocaleServiceProvider> providerClass,
226 Locale locale) {
227 for (Type type : getAdapterPreference()) {
228 LocaleProviderAdapter adapter = forType(type);
229 LocaleServiceProvider provider = adapter.getLocaleServiceProvider(providerClass);
230 if (provider != null) {
231 if (provider.isSupportedLocale(locale)) {
232 return adapter;
233 }
234 }
235 }
236 return null;
237 }
238
239 /**
240 * A utility method for implementing the default LocaleServiceProvider.isSupportedLocale
241 * for the JRE and CLDR adapters.
242 */
243 static boolean isSupportedLocale(Locale locale, LocaleProviderAdapter.Type type, Set<String> langtags) {
244 assert type == Type.JRE || type == Type.CLDR;
245 if (locale == Locale.ROOT) {
246 return true;
247 }
248 locale = locale.stripExtensions();
249 if (langtags.contains(locale.toLanguageTag())) {
250 return true;
251 }
252 if (type == LocaleProviderAdapter.Type.JRE) {
253 String oldname = locale.toString().replace('_', '-');
254 return langtags.contains(oldname);
255 }
256 return false;
257 }
258
259 public static Locale[] toLocaleArray(Set<String> tags) {
260 Locale[] locs = new Locale[tags.size() + 1];
261 int index = 0;
262 locs[index++] = Locale.ROOT;
263 for (String tag : tags) {
264 switch (tag) {
265 case "ja-JP-JP":
266 locs[index++] = JRELocaleConstants.JA_JP_JP;
267 break;
268 case "th-TH-TH":
269 locs[index++] = JRELocaleConstants.TH_TH_TH;
270 break;
271 default:
272 locs[index++] = Locale.forLanguageTag(tag);
|
42 import java.util.spi.LocaleNameProvider;
43 import java.util.spi.LocaleServiceProvider;
44 import java.util.spi.TimeZoneNameProvider;
45 import sun.util.cldr.CLDRLocaleProviderAdapter;
46 import sun.util.resources.LocaleData;
47
48 /**
49 * The LocaleProviderAdapter abstract class.
50 *
51 * @author Naoto Sato
52 * @author Masayoshi Okutsu
53 */
54 public abstract class LocaleProviderAdapter {
55 /**
56 * Adapter type.
57 */
58 public static enum Type {
59 JRE("sun.util.resources", "sun.text.resources"),
60 CLDR("sun.util.resources.cldr", "sun.text.resources.cldr"),
61 SPI,
62 HOST,
63 FALLBACK("sun.util.resources", "sun.text.resources");
64
65 private final String UTIL_RESOURCES_PACKAGE;
66 private final String TEXT_RESOURCES_PACKAGE;
67
68 private Type() {
69 this(null, null);
70 }
71
72 private Type(String util, String text) {
73 UTIL_RESOURCES_PACKAGE = util;
74 TEXT_RESOURCES_PACKAGE = text;
75 }
76
77 public String getUtilResourcesPackage() {
78 return UTIL_RESOURCES_PACKAGE;
79 }
80
81 public String getTextResourcesPackage() {
82 return TEXT_RESOURCES_PACKAGE;
83 }
95 /**
96 * JRE Locale Data Adapter instance
97 */
98 private static LocaleProviderAdapter jreLocaleProviderAdapter = new JRELocaleProviderAdapter();
99
100 /**
101 * SPI Locale Data Adapter instance
102 */
103 private static LocaleProviderAdapter spiLocaleProviderAdapter = new SPILocaleProviderAdapter();
104
105 /**
106 * CLDR Locale Data Adapter instance, if any.
107 */
108 private static LocaleProviderAdapter cldrLocaleProviderAdapter = null;
109
110 /**
111 * HOST Locale Data Adapter instance, if any.
112 */
113 private static LocaleProviderAdapter hostLocaleProviderAdapter = null;
114
115 /**
116 * FALLBACK Locale Data Adapter instance. It's basically the same with JRE, but only kicks
117 * in for the root locale.
118 */
119 private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null;
120
121 static {
122 String order = AccessController.doPrivileged(
123 new sun.security.action.GetPropertyAction("java.locale.providers"));
124 // Override adapterPreference with the properties one
125 if (order != null && order.length() != 0) {
126 String[] types = order.split(",");
127 List<Type> typeList = new ArrayList<>();
128 for (String type : types) {
129 try {
130 Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT));
131
132 // load adapter if necessary
133 switch (aType) {
134 case CLDR:
135 cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
136 break;
137 case HOST:
138 hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
139 break;
140 }
141 typeList.add(aType);
142 } catch (IllegalArgumentException | UnsupportedOperationException e) {
143 // could be caused by the user specifying wrong
144 // provider name or format in the system property
145 LocaleServiceProviderPool.config(LocaleProviderAdapter.class, e.toString());
146 }
147 }
148
149 if (!typeList.contains(Type.JRE)) {
150 // Append FALLBACK as the last resort.
151 fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
152 typeList.add(Type.FALLBACK);
153 }
154 adapterPreference = typeList.toArray(new Type[0]);
155 }
156 }
157
158
159 /**
160 * Returns the singleton instance for each adapter type
161 */
162 public static LocaleProviderAdapter forType(Type type) {
163 switch (type) {
164 case JRE:
165 return jreLocaleProviderAdapter;
166 case CLDR:
167 return cldrLocaleProviderAdapter;
168 case SPI:
169 return spiLocaleProviderAdapter;
170 case HOST:
171 return hostLocaleProviderAdapter;
172 case FALLBACK:
173 return fallbackLocaleProviderAdapter;
174 default:
175 throw new InternalError("unknown locale data adapter type");
176 }
177 }
178
179 public static LocaleProviderAdapter forJRE() {
180 return jreLocaleProviderAdapter;
181 }
182
183 public static LocaleProviderAdapter getResourceBundleBased() {
184 for (Type type : getAdapterPreference()) {
185 if (type == Type.JRE || type == Type.CLDR || type == Type.FALLBACK) {
186 return forType(type);
187 }
188 }
189 // Shouldn't happen.
190 throw new InternalError();
191 }
192 /**
193 * Returns the preference order of LocaleProviderAdapter.Type
194 */
195 public static Type[] getAdapterPreference() {
196 return adapterPreference;
197 }
198
199 /**
200 * Returns a LocaleProviderAdapter for the given locale service provider that
201 * best matches the given locale. This method returns the LocaleProviderAdapter
202 * for JRE if none is found for the given locale.
203 *
204 * @param providerClass the class for the locale service provider
205 * @param locale the desired locale.
210 // Fast look-up for the given locale
211 LocaleProviderAdapter adapter = findAdapter(providerClass, locale);
212 if (adapter != null) {
213 return adapter;
214 }
215
216 // Try finding an adapter in the normal candidate locales path of the given locale.
217 List<Locale> lookupLocales = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT)
218 .getCandidateLocales("", locale);
219 for (Locale loc : lookupLocales) {
220 if (loc.equals(locale)) {
221 // We've already done with this loc.
222 continue;
223 }
224 adapter = findAdapter(providerClass, loc);
225 if (adapter != null) {
226 return adapter;
227 }
228 }
229
230 // returns the adapter for FALLBACK as the last resort
231 if (fallbackLocaleProviderAdapter == null) {
232 fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
233 }
234 return fallbackLocaleProviderAdapter;
235 }
236
237 private static LocaleProviderAdapter findAdapter(Class<? extends LocaleServiceProvider> providerClass,
238 Locale locale) {
239 for (Type type : getAdapterPreference()) {
240 LocaleProviderAdapter adapter = forType(type);
241 LocaleServiceProvider provider = adapter.getLocaleServiceProvider(providerClass);
242 if (provider != null) {
243 if (provider.isSupportedLocale(locale)) {
244 return adapter;
245 }
246 }
247 }
248 return null;
249 }
250
251 /**
252 * A utility method for implementing the default LocaleServiceProvider.isSupportedLocale
253 * for the JRE, CLDR, and FALLBACK adapters.
254 */
255 static boolean isSupportedLocale(Locale locale, LocaleProviderAdapter.Type type, Set<String> langtags) {
256 assert type == Type.JRE || type == Type.CLDR || type == Type.FALLBACK;
257 if (locale == Locale.ROOT) {
258 return true;
259 }
260
261 if (type == Type.FALLBACK) {
262 // no other locales except ROOT are supported for FALLBACK
263 return false;
264 }
265
266 locale = locale.stripExtensions();
267 if (langtags.contains(locale.toLanguageTag())) {
268 return true;
269 }
270 if (type == Type.JRE) {
271 String oldname = locale.toString().replace('_', '-');
272 return langtags.contains(oldname);
273 }
274 return false;
275 }
276
277 public static Locale[] toLocaleArray(Set<String> tags) {
278 Locale[] locs = new Locale[tags.size() + 1];
279 int index = 0;
280 locs[index++] = Locale.ROOT;
281 for (String tag : tags) {
282 switch (tag) {
283 case "ja-JP-JP":
284 locs[index++] = JRELocaleConstants.JA_JP_JP;
285 break;
286 case "th-TH-TH":
287 locs[index++] = JRELocaleConstants.TH_TH_TH;
288 break;
289 default:
290 locs[index++] = Locale.forLanguageTag(tag);
|