• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
551