|
1 /** |
|
2 ******************************************************************************* |
|
3 * Copyright (C) 2001-2005, International Business Machines Corporation and * |
|
4 * others. All Rights Reserved. * |
|
5 ******************************************************************************* |
|
6 * |
|
7 ******************************************************************************* |
|
8 */ |
|
9 #ifndef ICULSERV_H |
|
10 #define ICULSERV_H |
|
11 |
|
12 #include "unicode/utypes.h" |
|
13 |
|
14 #if UCONFIG_NO_SERVICE |
|
15 |
|
16 U_NAMESPACE_BEGIN |
|
17 |
|
18 /* |
|
19 * Allow the declaration of APIs with pointers to ICUService |
|
20 * even when service is removed from the build. |
|
21 */ |
|
22 class ICULocaleService; |
|
23 |
|
24 U_NAMESPACE_END |
|
25 |
|
26 #else |
|
27 |
|
28 #include "unicode/unistr.h" |
|
29 #include "unicode/locid.h" |
|
30 #include "unicode/strenum.h" |
|
31 |
|
32 #include "hash.h" |
|
33 #include "uvector.h" |
|
34 |
|
35 #include "serv.h" |
|
36 #include "locutil.h" |
|
37 |
|
38 U_NAMESPACE_BEGIN |
|
39 |
|
40 class ICULocaleService; |
|
41 |
|
42 class LocaleKey; |
|
43 class LocaleKeyFactory; |
|
44 class SimpleLocaleKeyFactory; |
|
45 class ServiceListener; |
|
46 |
|
47 /* |
|
48 ****************************************************************** |
|
49 */ |
|
50 |
|
51 /** |
|
52 * A subclass of Key that implements a locale fallback mechanism. |
|
53 * The first locale to search for is the locale provided by the |
|
54 * client, and the fallback locale to search for is the current |
|
55 * default locale. If a prefix is present, the currentDescriptor |
|
56 * includes it before the locale proper, separated by "/". This |
|
57 * is the default key instantiated by ICULocaleService.</p> |
|
58 * |
|
59 * <p>Canonicalization adjusts the locale string so that the |
|
60 * section before the first understore is in lower case, and the rest |
|
61 * is in upper case, with no trailing underscores.</p> |
|
62 */ |
|
63 |
|
64 class U_COMMON_API LocaleKey : public ICUServiceKey { |
|
65 private: |
|
66 int32_t _kind; |
|
67 UnicodeString _primaryID; |
|
68 UnicodeString _fallbackID; |
|
69 UnicodeString _currentID; |
|
70 |
|
71 public: |
|
72 enum { |
|
73 KIND_ANY = -1 |
|
74 }; |
|
75 |
|
76 /** |
|
77 * Create a LocaleKey with canonical primary and fallback IDs. |
|
78 */ |
|
79 static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, |
|
80 const UnicodeString* canonicalFallbackID, |
|
81 UErrorCode& status); |
|
82 |
|
83 /** |
|
84 * Create a LocaleKey with canonical primary and fallback IDs. |
|
85 */ |
|
86 static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, |
|
87 const UnicodeString* canonicalFallbackID, |
|
88 int32_t kind, |
|
89 UErrorCode& status); |
|
90 |
|
91 protected: |
|
92 /** |
|
93 * PrimaryID is the user's requested locale string, |
|
94 * canonicalPrimaryID is this string in canonical form, |
|
95 * fallbackID is the current default locale's string in |
|
96 * canonical form. |
|
97 */ |
|
98 LocaleKey(const UnicodeString& primaryID, |
|
99 const UnicodeString& canonicalPrimaryID, |
|
100 const UnicodeString* canonicalFallbackID, |
|
101 int32_t kind); |
|
102 |
|
103 public: |
|
104 /** |
|
105 * Append the prefix associated with the kind, or nothing if the kind is KIND_ANY. |
|
106 */ |
|
107 virtual UnicodeString& prefix(UnicodeString& result) const; |
|
108 |
|
109 /** |
|
110 * Return the kind code associated with this key. |
|
111 */ |
|
112 virtual int32_t kind() const; |
|
113 |
|
114 /** |
|
115 * Return the canonicalID. |
|
116 */ |
|
117 virtual UnicodeString& canonicalID(UnicodeString& result) const; |
|
118 |
|
119 /** |
|
120 * Return the currentID. |
|
121 */ |
|
122 virtual UnicodeString& currentID(UnicodeString& result) const; |
|
123 |
|
124 /** |
|
125 * Return the (canonical) current descriptor, or null if no current id. |
|
126 */ |
|
127 virtual UnicodeString& currentDescriptor(UnicodeString& result) const; |
|
128 |
|
129 /** |
|
130 * Convenience method to return the locale corresponding to the (canonical) original ID. |
|
131 */ |
|
132 virtual Locale& canonicalLocale(Locale& result) const; |
|
133 |
|
134 /** |
|
135 * Convenience method to return the locale corresponding to the (canonical) current ID. |
|
136 */ |
|
137 virtual Locale& currentLocale(Locale& result) const; |
|
138 |
|
139 /** |
|
140 * If the key has a fallback, modify the key and return true, |
|
141 * otherwise return false.</p> |
|
142 * |
|
143 * <p>First falls back through the primary ID, then through |
|
144 * the fallbackID. The final fallback is the empty string, |
|
145 * unless the primary id was the empty string, in which case |
|
146 * there is no fallback. |
|
147 */ |
|
148 virtual UBool fallback(); |
|
149 |
|
150 /** |
|
151 * Return true if a key created from id matches, or would eventually |
|
152 * fallback to match, the canonical ID of this key. |
|
153 */ |
|
154 virtual UBool isFallbackOf(const UnicodeString& id) const; |
|
155 |
|
156 public: |
|
157 /** |
|
158 * UObject boilerplate. |
|
159 */ |
|
160 static UClassID U_EXPORT2 getStaticClassID(); |
|
161 |
|
162 virtual UClassID getDynamicClassID() const; |
|
163 |
|
164 /** |
|
165 * Destructor. |
|
166 */ |
|
167 virtual ~LocaleKey(); |
|
168 |
|
169 #ifdef SERVICE_DEBUG |
|
170 public: |
|
171 virtual UnicodeString& debug(UnicodeString& result) const; |
|
172 virtual UnicodeString& debugClass(UnicodeString& result) const; |
|
173 #endif |
|
174 |
|
175 }; |
|
176 |
|
177 /* |
|
178 ****************************************************************** |
|
179 */ |
|
180 |
|
181 /** |
|
182 * A subclass of ICUServiceFactory that uses LocaleKeys, and is able to |
|
183 * 'cover' more specific locales with more general locales that it |
|
184 * supports. |
|
185 * |
|
186 * <p>Coverage may be either of the values VISIBLE or INVISIBLE. |
|
187 * |
|
188 * <p>'Visible' indicates that the specific locale(s) supported by |
|
189 * the factory are registered in getSupportedIDs, 'Invisible' |
|
190 * indicates that they are not. |
|
191 * |
|
192 * <p>Localization of visible ids is handled |
|
193 * by the handling factory, regardless of kind. |
|
194 */ |
|
195 class U_COMMON_API LocaleKeyFactory : public ICUServiceFactory { |
|
196 protected: |
|
197 const UnicodeString _name; |
|
198 const int32_t _coverage; |
|
199 |
|
200 public: |
|
201 enum { |
|
202 /** |
|
203 * Coverage value indicating that the factory makes |
|
204 * its locales visible, and does not cover more specific |
|
205 * locales. |
|
206 */ |
|
207 VISIBLE = 0, |
|
208 |
|
209 /** |
|
210 * Coverage value indicating that the factory does not make |
|
211 * its locales visible, and does not cover more specific |
|
212 * locales. |
|
213 */ |
|
214 INVISIBLE = 1 |
|
215 }; |
|
216 |
|
217 /** |
|
218 * Destructor. |
|
219 */ |
|
220 virtual ~LocaleKeyFactory(); |
|
221 |
|
222 protected: |
|
223 /** |
|
224 * Constructor used by subclasses. |
|
225 */ |
|
226 LocaleKeyFactory(int32_t coverage); |
|
227 |
|
228 /** |
|
229 * Constructor used by subclasses. |
|
230 */ |
|
231 LocaleKeyFactory(int32_t coverage, const UnicodeString& name); |
|
232 |
|
233 /** |
|
234 * Implement superclass abstract method. This checks the currentID of |
|
235 * the key against the supported IDs, and passes the canonicalLocale and |
|
236 * kind off to handleCreate (which subclasses must implement). |
|
237 */ |
|
238 public: |
|
239 virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const; |
|
240 |
|
241 protected: |
|
242 virtual UBool handlesKey(const ICUServiceKey& key, UErrorCode& status) const; |
|
243 |
|
244 public: |
|
245 /** |
|
246 * Override of superclass method. This adjusts the result based |
|
247 * on the coverage rule for this factory. |
|
248 */ |
|
249 virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const; |
|
250 |
|
251 /** |
|
252 * Return a localized name for the locale represented by id. |
|
253 */ |
|
254 virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const; |
|
255 |
|
256 protected: |
|
257 /** |
|
258 * Utility method used by create(ICUServiceKey, ICUService). Subclasses can implement |
|
259 * this instead of create. The default returns NULL. |
|
260 */ |
|
261 virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const; |
|
262 |
|
263 /** |
|
264 * Return true if this id is one the factory supports (visible or |
|
265 * otherwise). |
|
266 */ |
|
267 // virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const; |
|
268 |
|
269 /** |
|
270 * Return the set of ids that this factory supports (visible or |
|
271 * otherwise). This can be called often and might need to be |
|
272 * cached if it is expensive to create. |
|
273 */ |
|
274 virtual const Hashtable* getSupportedIDs(UErrorCode& status) const; |
|
275 |
|
276 public: |
|
277 /** |
|
278 * UObject boilerplate. |
|
279 */ |
|
280 static UClassID U_EXPORT2 getStaticClassID(); |
|
281 |
|
282 virtual UClassID getDynamicClassID() const; |
|
283 |
|
284 #ifdef SERVICE_DEBUG |
|
285 public: |
|
286 virtual UnicodeString& debug(UnicodeString& result) const; |
|
287 virtual UnicodeString& debugClass(UnicodeString& result) const; |
|
288 #endif |
|
289 |
|
290 }; |
|
291 |
|
292 /* |
|
293 ****************************************************************** |
|
294 */ |
|
295 |
|
296 /** |
|
297 * A LocaleKeyFactory that just returns a single object for a kind/locale. |
|
298 */ |
|
299 |
|
300 class U_COMMON_API SimpleLocaleKeyFactory : public LocaleKeyFactory { |
|
301 private: |
|
302 UObject* _obj; |
|
303 UnicodeString _id; |
|
304 const int32_t _kind; |
|
305 |
|
306 public: |
|
307 SimpleLocaleKeyFactory(UObject* objToAdopt, |
|
308 const UnicodeString& locale, |
|
309 int32_t kind, |
|
310 int32_t coverage); |
|
311 |
|
312 SimpleLocaleKeyFactory(UObject* objToAdopt, |
|
313 const Locale& locale, |
|
314 int32_t kind, |
|
315 int32_t coverage); |
|
316 |
|
317 /** |
|
318 * Destructor. |
|
319 */ |
|
320 virtual ~SimpleLocaleKeyFactory(); |
|
321 |
|
322 /** |
|
323 * Override of superclass method. Returns the service object if kind/locale match. Service is not used. |
|
324 */ |
|
325 virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const; |
|
326 |
|
327 /** |
|
328 * Override of superclass method. This adjusts the result based |
|
329 * on the coverage rule for this factory. |
|
330 */ |
|
331 virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const; |
|
332 |
|
333 protected: |
|
334 /** |
|
335 * Return true if this id is equal to the locale name. |
|
336 */ |
|
337 //virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const; |
|
338 |
|
339 |
|
340 public: |
|
341 /** |
|
342 * UObject boilerplate. |
|
343 */ |
|
344 static UClassID U_EXPORT2 getStaticClassID(); |
|
345 |
|
346 virtual UClassID getDynamicClassID() const; |
|
347 |
|
348 #ifdef SERVICE_DEBUG |
|
349 public: |
|
350 virtual UnicodeString& debug(UnicodeString& result) const; |
|
351 virtual UnicodeString& debugClass(UnicodeString& result) const; |
|
352 #endif |
|
353 |
|
354 }; |
|
355 |
|
356 /* |
|
357 ****************************************************************** |
|
358 */ |
|
359 |
|
360 /** |
|
361 * A LocaleKeyFactory that creates a service based on the ICU locale data. |
|
362 * This is a base class for most ICU factories. Subclasses instantiate it |
|
363 * with a constructor that takes a bundle name, which determines the supported |
|
364 * IDs. Subclasses then override handleCreate to create the actual service |
|
365 * object. The default implementation returns a resource bundle. |
|
366 */ |
|
367 class U_COMMON_API ICUResourceBundleFactory : public LocaleKeyFactory |
|
368 { |
|
369 protected: |
|
370 UnicodeString _bundleName; |
|
371 |
|
372 public: |
|
373 /** |
|
374 * Convenience constructor that uses the main ICU bundle name. |
|
375 */ |
|
376 ICUResourceBundleFactory(); |
|
377 |
|
378 /** |
|
379 * A service factory based on ICU resource data in resources with |
|
380 * the given name. This should be a 'path' that can be passed to |
|
381 * ures_openAvailableLocales, such as U_ICUDATA or U_ICUDATA_COLL. |
|
382 * The empty string is equivalent to U_ICUDATA. |
|
383 */ |
|
384 ICUResourceBundleFactory(const UnicodeString& bundleName); |
|
385 |
|
386 /** |
|
387 * Destructor |
|
388 */ |
|
389 virtual ~ICUResourceBundleFactory(); |
|
390 |
|
391 protected: |
|
392 /** |
|
393 * Return the supported IDs. This is the set of all locale names in ICULocaleData. |
|
394 */ |
|
395 virtual const Hashtable* getSupportedIDs(UErrorCode& status) const; |
|
396 |
|
397 /** |
|
398 * Create the service. The default implementation returns the resource bundle |
|
399 * for the locale, ignoring kind, and service. |
|
400 */ |
|
401 virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const; |
|
402 |
|
403 public: |
|
404 /** |
|
405 * UObject boilerplate. |
|
406 */ |
|
407 static UClassID U_EXPORT2 getStaticClassID(); |
|
408 virtual UClassID getDynamicClassID() const; |
|
409 |
|
410 |
|
411 #ifdef SERVICE_DEBUG |
|
412 public: |
|
413 virtual UnicodeString& debug(UnicodeString& result) const; |
|
414 virtual UnicodeString& debugClass(UnicodeString& result) const; |
|
415 #endif |
|
416 |
|
417 }; |
|
418 |
|
419 /* |
|
420 ****************************************************************** |
|
421 */ |
|
422 |
|
423 class U_COMMON_API ICULocaleService : public ICUService |
|
424 { |
|
425 private: |
|
426 Locale fallbackLocale; |
|
427 UnicodeString fallbackLocaleName; |
|
428 UMTX llock; |
|
429 |
|
430 public: |
|
431 /** |
|
432 * Construct an ICULocaleService. |
|
433 */ |
|
434 ICULocaleService(); |
|
435 |
|
436 /** |
|
437 * Construct an ICULocaleService with a name (useful for debugging). |
|
438 */ |
|
439 ICULocaleService(const UnicodeString& name); |
|
440 |
|
441 /** |
|
442 * Destructor. |
|
443 */ |
|
444 virtual ~ICULocaleService(); |
|
445 |
|
446 #if 0 |
|
447 // redeclare because of overload resolution rules? |
|
448 // no, causes ambiguities since both UnicodeString and Locale have constructors that take a const char* |
|
449 // need some compiler flag to remove warnings |
|
450 UObject* get(const UnicodeString& descriptor, UErrorCode& status) const { |
|
451 return ICUService::get(descriptor, status); |
|
452 } |
|
453 |
|
454 UObject* get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const { |
|
455 return ICUService::get(descriptor, actualReturn, status); |
|
456 } |
|
457 #endif |
|
458 |
|
459 /** |
|
460 * Convenience override for callers using locales. This calls |
|
461 * get(Locale, int, Locale[]) with KIND_ANY for kind and null for |
|
462 * actualReturn. |
|
463 */ |
|
464 UObject* get(const Locale& locale, UErrorCode& status) const; |
|
465 |
|
466 /** |
|
467 * Convenience override for callers using locales. This calls |
|
468 * get(Locale, int, Locale[]) with a null actualReturn. |
|
469 */ |
|
470 UObject* get(const Locale& locale, int32_t kind, UErrorCode& status) const; |
|
471 |
|
472 /** |
|
473 * Convenience override for callers using locales. This calls |
|
474 * get(Locale, String, Locale[]) with a null kind. |
|
475 */ |
|
476 UObject* get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const; |
|
477 |
|
478 /** |
|
479 * Convenience override for callers using locales. This uses |
|
480 * createKey(Locale.toString(), kind) to create a key, calls getKey, and then |
|
481 * if actualReturn is not null, returns the actualResult from |
|
482 * getKey (stripping any prefix) into a Locale. |
|
483 */ |
|
484 UObject* get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const; |
|
485 |
|
486 /** |
|
487 * Convenience override for callers using locales. This calls |
|
488 * registerObject(Object, Locale, int32_t kind, int coverage) |
|
489 * passing KIND_ANY for the kind, and VISIBLE for the coverage. |
|
490 */ |
|
491 virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status); |
|
492 |
|
493 /** |
|
494 * Convenience function for callers using locales. This calls |
|
495 * registerObject(Object, Locale, int kind, int coverage) |
|
496 * passing VISIBLE for the coverage. |
|
497 */ |
|
498 virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status); |
|
499 |
|
500 /** |
|
501 * Convenience function for callers using locales. This instantiates |
|
502 * a SimpleLocaleKeyFactory, and registers the factory. |
|
503 */ |
|
504 virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status); |
|
505 |
|
506 |
|
507 /** |
|
508 * (Stop compiler from complaining about hidden overrides.) |
|
509 * Since both UnicodeString and Locale have constructors that take const char*, adding a public |
|
510 * method that takes UnicodeString causes ambiguity at call sites that use const char*. |
|
511 * We really need a flag that is understood by all compilers that will suppress the warning about |
|
512 * hidden overrides. |
|
513 */ |
|
514 virtual URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status); |
|
515 |
|
516 /** |
|
517 * Convenience method for callers using locales. This returns the standard |
|
518 * service ID enumeration. |
|
519 */ |
|
520 virtual StringEnumeration* getAvailableLocales(void) const; |
|
521 |
|
522 protected: |
|
523 |
|
524 /** |
|
525 * Return the name of the current fallback locale. If it has changed since this was |
|
526 * last accessed, the service cache is cleared. |
|
527 */ |
|
528 const UnicodeString& validateFallbackLocale() const; |
|
529 |
|
530 /** |
|
531 * Override superclass createKey method. |
|
532 */ |
|
533 virtual ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const; |
|
534 |
|
535 /** |
|
536 * Additional createKey that takes a kind. |
|
537 */ |
|
538 virtual ICUServiceKey* createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const; |
|
539 |
|
540 friend class ServiceEnumeration; |
|
541 }; |
|
542 |
|
543 U_NAMESPACE_END |
|
544 |
|
545 /* UCONFIG_NO_SERVICE */ |
|
546 #endif |
|
547 |
|
548 /* ICULSERV_H */ |
|
549 #endif |
|
550 |