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