Home | History | Annotate | Download | only in common
      1 /**
      2  *******************************************************************************
      3  * Copyright (C) 2001-2011, 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 
    429  public:
    430   /**
    431    * Construct an ICULocaleService.
    432    */
    433   ICULocaleService();
    434 
    435   /**
    436    * Construct an ICULocaleService with a name (useful for debugging).
    437    */
    438   ICULocaleService(const UnicodeString& name);
    439 
    440   /**
    441    * Destructor.
    442    */
    443   virtual ~ICULocaleService();
    444 
    445 #if 0
    446   // redeclare because of overload resolution rules?
    447   // no, causes ambiguities since both UnicodeString and Locale have constructors that take a const char*
    448   // need some compiler flag to remove warnings
    449   UObject* get(const UnicodeString& descriptor, UErrorCode& status) const {
    450     return ICUService::get(descriptor, status);
    451   }
    452 
    453   UObject* get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const {
    454     return ICUService::get(descriptor, actualReturn, status);
    455   }
    456 #endif
    457 
    458   /**
    459    * Convenience override for callers using locales.  This calls
    460    * get(Locale, int, Locale[]) with KIND_ANY for kind and null for
    461    * actualReturn.
    462    */
    463   UObject* get(const Locale& locale, UErrorCode& status) const;
    464 
    465   /**
    466    * Convenience override for callers using locales.  This calls
    467    * get(Locale, int, Locale[]) with a null actualReturn.
    468    */
    469   UObject* get(const Locale& locale, int32_t kind, UErrorCode& status) const;
    470 
    471   /**
    472    * Convenience override for callers using locales. This calls
    473    * get(Locale, String, Locale[]) with a null kind.
    474    */
    475   UObject* get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const;
    476 
    477   /**
    478    * Convenience override for callers using locales.  This uses
    479    * createKey(Locale.toString(), kind) to create a key, calls getKey, and then
    480    * if actualReturn is not null, returns the actualResult from
    481    * getKey (stripping any prefix) into a Locale.
    482    */
    483   UObject* get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const;
    484 
    485   /**
    486    * Convenience override for callers using locales.  This calls
    487    * registerObject(Object, Locale, int32_t kind, int coverage)
    488    * passing KIND_ANY for the kind, and VISIBLE for the coverage.
    489    */
    490   virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status);
    491 
    492   /**
    493    * Convenience function for callers using locales.  This calls
    494    * registerObject(Object, Locale, int kind, int coverage)
    495    * passing VISIBLE for the coverage.
    496    */
    497   virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status);
    498 
    499   /**
    500    * Convenience function for callers using locales.  This  instantiates
    501    * a SimpleLocaleKeyFactory, and registers the factory.
    502    */
    503   virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status);
    504 
    505 
    506   /**
    507    * (Stop compiler from complaining about hidden overrides.)
    508    * Since both UnicodeString and Locale have constructors that take const char*, adding a public
    509    * method that takes UnicodeString causes ambiguity at call sites that use const char*.
    510    * We really need a flag that is understood by all compilers that will suppress the warning about
    511    * hidden overrides.
    512    */
    513   virtual URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status);
    514 
    515   /**
    516    * Convenience method for callers using locales.  This returns the standard
    517    * service ID enumeration.
    518    */
    519   virtual StringEnumeration* getAvailableLocales(void) const;
    520 
    521  protected:
    522 
    523   /**
    524    * Return the name of the current fallback locale.  If it has changed since this was
    525    * last accessed, the service cache is cleared.
    526    */
    527   const UnicodeString& validateFallbackLocale() const;
    528 
    529   /**
    530    * Override superclass createKey method.
    531    */
    532   virtual ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const;
    533 
    534   /**
    535    * Additional createKey that takes a kind.
    536    */
    537   virtual ICUServiceKey* createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const;
    538 
    539   friend class ServiceEnumeration;
    540 };
    541 
    542 U_NAMESPACE_END
    543 
    544     /* UCONFIG_NO_SERVICE */
    545 #endif
    546 
    547     /* ICULSERV_H */
    548 #endif
    549 
    550