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