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.       *
      6  * All Rights Reserved.                                                        *
      7  *******************************************************************************
      8  */
      9 
     10 #ifndef ICUSERV_H
     11 #define ICUSERV_H
     12 
     13 #include "unicode/utypes.h"
     14 
     15 #if UCONFIG_NO_SERVICE
     16 
     17 U_NAMESPACE_BEGIN
     18 
     19 /*
     20  * Allow the declaration of APIs with pointers to ICUService
     21  * even when service is removed from the build.
     22  */
     23 class ICUService;
     24 
     25 U_NAMESPACE_END
     26 
     27 #else
     28 
     29 #include "unicode/unistr.h"
     30 #include "unicode/locid.h"
     31 #include "unicode/umisc.h"
     32 
     33 #include "hash.h"
     34 #include "uvector.h"
     35 #include "servnotf.h"
     36 
     37 class ICUServiceTest;
     38 
     39 U_NAMESPACE_BEGIN
     40 
     41 class ICUServiceKey;
     42 class ICUServiceFactory;
     43 class SimpleFactory;
     44 class ServiceListener;
     45 class ICUService;
     46 
     47 class DNCache;
     48 
     49 /*******************************************************************
     50  * ICUServiceKey
     51  */
     52 
     53 /**
     54  * <p>ICUServiceKeys are used to communicate with factories to
     55  * generate an instance of the service.  ICUServiceKeys define how
     56  * ids are canonicalized, provide both a current id and a current
     57  * descriptor to use in querying the cache and factories, and
     58  * determine the fallback strategy.</p>
     59  *
     60  * <p>ICUServiceKeys provide both a currentDescriptor and a currentID.
     61  * The descriptor contains an optional prefix, followed by '/'
     62  * and the currentID.  Factories that handle complex keys,
     63  * for example number format factories that generate multiple
     64  * kinds of formatters for the same locale, use the descriptor
     65  * to provide a fully unique identifier for the service object,
     66  * while using the currentID (in this case, the locale string),
     67  * as the visible IDs that can be localized.</p>
     68  *
     69  * <p>The default implementation of ICUServiceKey has no fallbacks and
     70  * has no custom descriptors.</p>
     71  */
     72 class U_COMMON_API ICUServiceKey : public UObject {
     73  private:
     74   const UnicodeString _id;
     75 
     76  protected:
     77   static const UChar PREFIX_DELIMITER;
     78 
     79  public:
     80 
     81   /**
     82    * <p>Construct a key from an id.</p>
     83    *
     84    * @param id the ID from which to construct the key.
     85    */
     86   ICUServiceKey(const UnicodeString& id);
     87 
     88   /**
     89    * <p>Virtual destructor.</p>
     90    */
     91   virtual ~ICUServiceKey();
     92 
     93  /**
     94   * <p>Return the original ID used to construct this key.</p>
     95   *
     96   * @return the ID used to construct this key.
     97   */
     98   virtual const UnicodeString& getID() const;
     99 
    100  /**
    101   * <p>Return the canonical version of the original ID.  This implementation
    102   * appends the original ID to result.  Result is returned as a convenience.</p>
    103   *
    104   * @param result the output parameter to which the id will be appended.
    105   * @return the modified result.
    106   */
    107   virtual UnicodeString& canonicalID(UnicodeString& result) const;
    108 
    109  /**
    110   * <p>Return the (canonical) current ID.  This implementation appends
    111   * the canonical ID to result.  Result is returned as a convenience.</p>
    112   *
    113   * @param result the output parameter to which the current id will be appended.
    114   * @return the modified result.
    115   */
    116   virtual UnicodeString& currentID(UnicodeString& result) const;
    117 
    118  /**
    119   * <p>Return the current descriptor.  This implementation appends
    120   * the current descriptor to result.  Result is returned as a convenience.</p>
    121   *
    122   * <p>The current descriptor is used to fully
    123   * identify an instance of the service in the cache.  A
    124   * factory may handle all descriptors for an ID, or just a
    125   * particular descriptor.  The factory can either parse the
    126   * descriptor or use custom API on the key in order to
    127   * instantiate the service.</p>
    128   *
    129   * @param result the output parameter to which the current id will be appended.
    130   * @return the modified result.
    131   */
    132   virtual UnicodeString& currentDescriptor(UnicodeString& result) const;
    133 
    134  /**
    135   * <p>If the key has a fallback, modify the key and return true,
    136   * otherwise return false.  The current ID will change if there
    137   * is a fallback.  No currentIDs should be repeated, and fallback
    138   * must eventually return false.  This implementation has no fallbacks
    139   * and always returns false.</p>
    140   *
    141   * @return TRUE if the ICUServiceKey changed to a valid fallback value.
    142   */
    143   virtual UBool fallback();
    144 
    145  /**
    146   * <p>Return TRUE if a key created from id matches, or would eventually
    147   * fallback to match, the canonical ID of this ICUServiceKey.</p>
    148   *
    149   * @param id the id to test.
    150   * @return TRUE if this ICUServiceKey's canonical ID is a fallback of id.
    151   */
    152   virtual UBool isFallbackOf(const UnicodeString& id) const;
    153 
    154  /**
    155   * <p>Return the prefix.  This implementation leaves result unchanged.
    156   * Result is returned as a convenience.</p>
    157   *
    158   * @param result the output parameter to which the prefix will be appended.
    159   * @return the modified result.
    160   */
    161   virtual UnicodeString& prefix(UnicodeString& result) const;
    162 
    163  /**
    164   * <p>A utility to parse the prefix out of a descriptor string.  Only
    165   * the (undelimited) prefix, if any, remains in result.  Result is returned as a
    166   * convenience.</p>
    167   *
    168   * @param result an input/output parameter that on entry is a descriptor, and
    169   * on exit is the prefix of that descriptor.
    170   * @return the modified result.
    171   */
    172   static UnicodeString& parsePrefix(UnicodeString& result);
    173 
    174   /**
    175   * <p>A utility to parse the suffix out of a descriptor string.  Only
    176   * the (undelimited) suffix, if any, remains in result.  Result is returned as a
    177   * convenience.</p>
    178   *
    179   * @param result an input/output parameter that on entry is a descriptor, and
    180   * on exit is the suffix of that descriptor.
    181   * @return the modified result.
    182   */
    183   static UnicodeString& parseSuffix(UnicodeString& result);
    184 
    185 public:
    186   /**
    187    * UObject RTTI boilerplate.
    188    */
    189   static UClassID U_EXPORT2 getStaticClassID();
    190 
    191   /**
    192    * UObject RTTI boilerplate.
    193    */
    194   virtual UClassID getDynamicClassID() const;
    195 
    196 #ifdef SERVICE_DEBUG
    197  public:
    198   virtual UnicodeString& debug(UnicodeString& result) const;
    199   virtual UnicodeString& debugClass(UnicodeString& result) const;
    200 #endif
    201 
    202 };
    203 
    204  /*******************************************************************
    205   * ICUServiceFactory
    206   */
    207 
    208  /**
    209   * <p>An implementing ICUServiceFactory generates the service objects maintained by the
    210   * service.  A factory generates a service object from a key,
    211   * updates id->factory mappings, and returns the display name for
    212   * a supported id.</p>
    213   */
    214 class U_COMMON_API ICUServiceFactory : public UObject {
    215  public:
    216     virtual ~ICUServiceFactory();
    217 
    218     /**
    219      * <p>Create a service object from the key, if this factory
    220      * supports the key.  Otherwise, return NULL.</p>
    221      *
    222      * <p>If the factory supports the key, then it can call
    223      * the service's getKey(ICUServiceKey, String[], ICUServiceFactory) method
    224      * passing itself as the factory to get the object that
    225      * the service would have created prior to the factory's
    226      * registration with the service.  This can change the
    227      * key, so any information required from the key should
    228      * be extracted before making such a callback.</p>
    229      *
    230      * @param key the service key.
    231      * @param service the service with which this factory is registered.
    232      * @param status the error code status.
    233      * @return the service object, or NULL if the factory does not support the key.
    234      */
    235     virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const = 0;
    236 
    237     /**
    238      * <p>Update result to reflect the IDs (not descriptors) that this
    239      * factory publicly handles.  Result contains mappings from ID to
    240      * factory.  On entry it will contain all (visible) mappings from
    241      * previously-registered factories.</p>
    242      *
    243      * <p>This function, together with getDisplayName, are used to
    244      * support ICUService::getDisplayNames.  The factory determines
    245      * which IDs (of those it supports) it will make visible, and of
    246      * those, which it will provide localized display names for.  In
    247      * most cases it will register mappings from all IDs it supports
    248      * to itself.</p>
    249      *
    250      * @param result the mapping table to update.
    251      * @param status the error code status.
    252      */
    253     virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const = 0;
    254 
    255     /**
    256      * <p>Return, in result, the display name of the id in the provided locale.
    257      * This is an id, not a descriptor.  If the id is
    258      * not visible, sets result to bogus.  If the
    259      * incoming result is bogus, it remains bogus.  Result is returned as a
    260      * convenience.  Results are not defined if id is not one supported by this
    261          * factory.</p>
    262      *
    263      * @param id a visible id supported by this factory.
    264      * @param locale the locale for which to generate the corresponding localized display name.
    265      * @param result output parameter to hold the display name.
    266      * @return result.
    267      */
    268     virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const = 0;
    269 };
    270 
    271 /*
    272  ******************************************************************
    273  */
    274 
    275  /**
    276   * <p>A default implementation of factory.  This provides default
    277   * implementations for subclasses, and implements a singleton
    278   * factory that matches a single ID and returns a single
    279   * (possibly deferred-initialized) instance.  This implements
    280   * updateVisibleIDs to add a mapping from its ID to itself
    281   * if visible is true, or to remove any existing mapping
    282   * for its ID if visible is false.  No localization of display
    283   * names is performed.</p>
    284   */
    285 class U_COMMON_API SimpleFactory : public ICUServiceFactory {
    286  protected:
    287   UObject* _instance;
    288   const UnicodeString _id;
    289   const UBool _visible;
    290 
    291  public:
    292   /**
    293    * <p>Construct a SimpleFactory that maps a single ID to a single
    294    * service instance.  If visible is TRUE, the ID will be visible.
    295    * The instance must not be NULL.  The SimpleFactory will adopt
    296    * the instance, which must not be changed subsequent to this call.</p>
    297    *
    298    * @param instanceToAdopt the service instance to adopt.
    299    * @param id the ID to assign to this service instance.
    300    * @param visible if TRUE, the ID will be visible.
    301    */
    302   SimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible = TRUE);
    303 
    304   /**
    305    * <p>Destructor.</p>
    306    */
    307   virtual ~SimpleFactory();
    308 
    309   /**
    310    * <p>This implementation returns a clone of the service instance if the factory's ID is equal to
    311    * the key's currentID.  Service and prefix are ignored.</p>
    312    *
    313    * @param key the service key.
    314    * @param service the service with which this factory is registered.
    315    * @param status the error code status.
    316    * @return the service object, or NULL if the factory does not support the key.
    317    */
    318   virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;
    319 
    320   /**
    321    * <p>This implementation adds a mapping from ID -> this to result if visible is TRUE,
    322    * otherwise it removes ID from result.</p>
    323    *
    324    * @param result the mapping table to update.
    325    * @param status the error code status.
    326    */
    327   virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;
    328 
    329   /**
    330    * <p>This implementation returns the factory ID if it equals id and visible is TRUE,
    331    * otherwise it returns the empty string.  (This implementation provides
    332    * no localized id information.)</p>
    333    *
    334    * @param id a visible id supported by this factory.
    335    * @param locale the locale for which to generate the corresponding localized display name.
    336    * @param result output parameter to hold the display name.
    337    * @return result.
    338    */
    339   virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const;
    340 
    341 public:
    342  /**
    343   * UObject RTTI boilerplate.
    344   */
    345   static UClassID U_EXPORT2 getStaticClassID();
    346 
    347  /**
    348   * UObject RTTI boilerplate.
    349   */
    350   virtual UClassID getDynamicClassID() const;
    351 
    352 #ifdef SERVICE_DEBUG
    353  public:
    354   virtual UnicodeString& debug(UnicodeString& toAppendTo) const;
    355   virtual UnicodeString& debugClass(UnicodeString& toAppendTo) const;
    356 #endif
    357 
    358 };
    359 
    360 /*
    361  ******************************************************************
    362  */
    363 
    364 /**
    365  * <p>ServiceListener is the listener that ICUService provides by default.
    366  * ICUService will notifiy this listener when factories are added to
    367  * or removed from the service.  Subclasses can provide
    368  * different listener interfaces that extend EventListener, and modify
    369  * acceptsListener and notifyListener as appropriate.</p>
    370  */
    371 class U_COMMON_API ServiceListener : public EventListener {
    372 public:
    373     virtual ~ServiceListener();
    374 
    375     /**
    376      * <p>This method is called when the service changes. At the time of the
    377      * call this listener is registered with the service.  It must
    378      * not modify the notifier in the context of this call.</p>
    379      *
    380      * @param service the service that changed.
    381      */
    382     virtual void serviceChanged(const ICUService& service) const = 0;
    383 
    384 public:
    385     /**
    386      * UObject RTTI boilerplate.
    387      */
    388     static UClassID U_EXPORT2 getStaticClassID();
    389 
    390     /**
    391      * UObject RTTI boilerplate.
    392      */
    393     virtual UClassID getDynamicClassID() const;
    394 
    395 };
    396 
    397 /*
    398  ******************************************************************
    399  */
    400 
    401 /**
    402  * <p>A StringPair holds a displayName/ID pair.  ICUService uses it
    403  * as the array elements returned by getDisplayNames.
    404  */
    405 class U_COMMON_API StringPair : public UMemory {
    406 public:
    407   /**
    408    * <p>The display name of the pair.</p>
    409    */
    410   const UnicodeString displayName;
    411 
    412   /**
    413    * <p>The ID of the pair.</p>
    414    */
    415   const UnicodeString id;
    416 
    417   /**
    418    * <p>Creates a string pair from a displayName and an ID.</p>
    419    *
    420    * @param displayName the displayName.
    421    * @param id the ID.
    422    * @param status the error code status.
    423    * @return a StringPair if the creation was successful, otherwise NULL.
    424    */
    425   static StringPair* create(const UnicodeString& displayName,
    426                             const UnicodeString& id,
    427                             UErrorCode& status);
    428 
    429   /**
    430    * <p>Return TRUE if either string of the pair is bogus.</p>
    431    * @return TRUE if either string of the pair is bogus.
    432    */
    433   UBool isBogus() const;
    434 
    435 private:
    436   StringPair(const UnicodeString& displayName, const UnicodeString& id);
    437 };
    438 
    439 /*******************************************************************
    440  * ICUService
    441  */
    442 
    443  /**
    444  * <p>A Service provides access to service objects that implement a
    445  * particular service, e.g. transliterators.  Users provide a String
    446  * id (for example, a locale string) to the service, and get back an
    447  * object for that id.  Service objects can be any kind of object.  A
    448  * new service object is returned for each query. The caller is
    449  * responsible for deleting it.</p>
    450  *
    451  * <p>Services 'canonicalize' the query ID and use the canonical ID to
    452  * query for the service.  The service also defines a mechanism to
    453  * 'fallback' the ID multiple times.  Clients can optionally request
    454  * the actual ID that was matched by a query when they use an ID to
    455  * retrieve a service object.</p>
    456  *
    457  * <p>Service objects are instantiated by ICUServiceFactory objects
    458  * registered with the service.  The service queries each
    459  * ICUServiceFactory in turn, from most recently registered to
    460  * earliest registered, until one returns a service object.  If none
    461  * responds with a service object, a fallback ID is generated, and the
    462  * process repeats until a service object is returned or until the ID
    463  * has no further fallbacks.</p>
    464  *
    465  * <p>In ICU 2.4, UObject (the base class of service instances) does
    466  * not define a polymorphic clone function.  ICUService uses clones to
    467  * manage ownership.  Thus, for now, ICUService defines an abstract
    468  * method, cloneInstance, that clients must implement to create clones
    469  * of the service instances.  This may change in future releases of
    470  * ICU.</p>
    471  *
    472  * <p>ICUServiceFactories can be dynamically registered and
    473  * unregistered with the service.  When registered, an
    474  * ICUServiceFactory is installed at the head of the factory list, and
    475  * so gets 'first crack' at any keys or fallback keys.  When
    476  * unregistered, it is removed from the service and can no longer be
    477  * located through it.  Service objects generated by this factory and
    478  * held by the client are unaffected.</p>
    479  *
    480  * <p>If a service has variants (e.g., the different variants of
    481  * BreakIterator) an ICUServiceFactory can use the prefix of the
    482  * ICUServiceKey to determine the variant of a service to generate.
    483  * If it does not support all variants, it can request
    484  * previously-registered factories to handle the ones it does not
    485  * support.</p>
    486  *
    487  * <p>ICUService uses ICUServiceKeys to query factories and perform
    488  * fallback.  The ICUServiceKey defines the canonical form of the ID,
    489  * and implements the fallback strategy.  Custom ICUServiceKeys can be
    490  * defined that parse complex IDs into components that
    491  * ICUServiceFactories can more easily use.  The ICUServiceKey can
    492  * cache the results of this parsing to save repeated effort.
    493  * ICUService provides convenience APIs that take UnicodeStrings and
    494  * generate default ICUServiceKeys for use in querying.</p>
    495  *
    496  * <p>ICUService provides API to get the list of IDs publicly
    497  * supported by the service (although queries aren't restricted to
    498  * this list).  This list contains only 'simple' IDs, and not fully
    499  * unique IDs.  ICUServiceFactories are associated with each simple ID
    500  * and the responsible factory can also return a human-readable
    501  * localized version of the simple ID, for use in user interfaces.
    502  * ICUService can also provide an array of the all the localized
    503  * visible IDs and their corresponding internal IDs.</p>
    504  *
    505  * <p>ICUService implements ICUNotifier, so that clients can register
    506  * to receive notification when factories are added or removed from
    507  * the service.  ICUService provides a default EventListener
    508  * subinterface, ServiceListener, which can be registered with the
    509  * service.  When the service changes, the ServiceListener's
    510  * serviceChanged method is called with the service as the
    511  * argument.</p>
    512  *
    513  * <p>The ICUService API is both rich and generic, and it is expected
    514  * that most implementations will statically 'wrap' ICUService to
    515  * present a more appropriate API-- for example, to declare the type
    516  * of the objects returned from get, to limit the factories that can
    517  * be registered with the service, or to define their own listener
    518  * interface with a custom callback method.  They might also customize
    519  * ICUService by overriding it, for example, to customize the
    520  * ICUServiceKey and fallback strategy.  ICULocaleService is a
    521  * subclass of ICUService that uses Locale names as IDs and uses
    522  * ICUServiceKeys that implement the standard resource bundle fallback
    523  * strategy.  Most clients will wish to subclass it instead of
    524  * ICUService.</p>
    525  */
    526 class U_COMMON_API ICUService : public ICUNotifier {
    527  protected:
    528     /**
    529      * Name useful for debugging.
    530      */
    531     const UnicodeString name;
    532 
    533  private:
    534 
    535     /**
    536      * Timestamp so iterators can be fail-fast.
    537      */
    538     uint32_t timestamp;
    539 
    540     /**
    541      * All the factories registered with this service.
    542      */
    543     UVector* factories;
    544 
    545     /**
    546      * The service cache.
    547      */
    548     Hashtable* serviceCache;
    549 
    550     /**
    551      * The ID cache.
    552      */
    553     Hashtable* idCache;
    554 
    555     /**
    556      * The name cache.
    557      */
    558     DNCache* dnCache;
    559 
    560     /**
    561      * Constructor.
    562      */
    563  public:
    564     /**
    565      * <p>Construct a new ICUService.</p>
    566      */
    567     ICUService();
    568 
    569     /**
    570      * <p>Construct with a name (useful for debugging).</p>
    571      *
    572      * @param name a name to use in debugging.
    573      */
    574     ICUService(const UnicodeString& name);
    575 
    576     /**
    577      * <p>Destructor.</p>
    578      */
    579     virtual ~ICUService();
    580 
    581     /**
    582      * <p>Return the name of this service. This will be the empty string if none was assigned.
    583      * Returns result as a convenience.</p>
    584      *
    585      * @param result an output parameter to contain the name of this service.
    586      * @return the name of this service.
    587      */
    588     UnicodeString& getName(UnicodeString& result) const;
    589 
    590     /**
    591      * <p>Convenience override for get(ICUServiceKey&, UnicodeString*). This uses
    592      * createKey to create a key for the provided descriptor.</p>
    593      *
    594      * @param descriptor the descriptor.
    595      * @param status the error code status.
    596      * @return the service instance, or NULL.
    597      */
    598     UObject* get(const UnicodeString& descriptor, UErrorCode& status) const;
    599 
    600     /**
    601      * <p>Convenience override for get(ICUServiceKey&, UnicodeString*).  This uses
    602      * createKey to create a key from the provided descriptor.</p>
    603      *
    604      * @param descriptor the descriptor.
    605      * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
    606      * @param status the error code status.
    607      * @return the service instance, or NULL.
    608      */
    609     UObject* get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const;
    610 
    611     /**
    612      * <p>Convenience override for get(ICUServiceKey&, UnicodeString*).</p>
    613      *
    614      * @param key the key.
    615      * @param status the error code status.
    616      * @return the service instance, or NULL.
    617      */
    618     UObject* getKey(ICUServiceKey& key, UErrorCode& status) const;
    619 
    620     /**
    621      * <p>Given a key, return a service object, and, if actualReturn
    622      * is not NULL, the descriptor with which it was found in the
    623      * first element of actualReturn.  If no service object matches
    624      * this key, returns NULL and leaves actualReturn unchanged.</p>
    625      *
    626      * <p>This queries the cache using the key's descriptor, and if no
    627      * object in the cache matches, tries the key on each
    628      * registered factory, in order.  If none generates a service
    629      * object for the key, repeats the process with each fallback of
    630      * the key, until either a factory returns a service object, or the key
    631      * has no fallback.  If no object is found, the result of handleDefault
    632      * is returned.</p>
    633      *
    634      * <p>Subclasses can override this method to further customize the
    635      * result before returning it.
    636      *
    637      * @param key the key.
    638      * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
    639      * @param status the error code status.
    640      * @return the service instance, or NULL.
    641      */
    642     virtual UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const;
    643 
    644     /**
    645      * <p>This version of getKey is only called by ICUServiceFactories within the scope
    646      * of a previous getKey call, to determine what previously-registered factories would
    647      * have returned.  For details, see getKey(ICUServiceKey&, UErrorCode&).  Subclasses
    648      * should not call it directly, but call through one of the other get functions.</p>
    649      *
    650      * @param key the key.
    651      * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
    652      * @param factory the factory making the recursive call.
    653      * @param status the error code status.
    654      * @return the service instance, or NULL.
    655      */
    656     UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUServiceFactory* factory, UErrorCode& status) const;
    657 
    658     /**
    659      * <p>Convenience override for getVisibleIDs(String) that passes null
    660      * as the fallback, thus returning all visible IDs.</p>
    661      *
    662      * @param result a vector to hold the returned IDs.
    663      * @param status the error code status.
    664      * @return the result vector.
    665      */
    666     UVector& getVisibleIDs(UVector& result, UErrorCode& status) const;
    667 
    668     /**
    669      * <p>Return a snapshot of the visible IDs for this service.  This
    670      * list will not change as ICUServiceFactories are added or removed, but the
    671      * supported IDs will, so there is no guarantee that all and only
    672      * the IDs in the returned list will be visible and supported by the
    673      * service in subsequent calls.</p>
    674      *
    675      * <p>The IDs are returned as pointers to UnicodeStrings.  The
    676      * caller owns the IDs.  Previous contents of result are discarded before
    677      * new elements, if any, are added.</p>
    678      *
    679      * <p>matchID is passed to createKey to create a key.  If the key
    680      * is not NULL, its isFallbackOf method is used to filter out IDs
    681      * that don't match the key or have it as a fallback.</p>
    682      *
    683      * @param result a vector to hold the returned IDs.
    684      * @param matchID an ID used to filter the result, or NULL if all IDs are desired.
    685      * @param status the error code status.
    686      * @return the result vector.
    687      */
    688     UVector& getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorCode& status) const;
    689 
    690     /**
    691      * <p>Convenience override for getDisplayName(const UnicodeString&, const Locale&, UnicodeString&) that
    692      * uses the current default locale.</p>
    693      *
    694      * @param id the ID for which to retrieve the localized displayName.
    695      * @param result an output parameter to hold the display name.
    696      * @return the modified result.
    697      */
    698     UnicodeString& getDisplayName(const UnicodeString& id, UnicodeString& result) const;
    699 
    700     /**
    701      * <p>Given a visible ID, return the display name in the requested locale.
    702      * If there is no directly supported ID corresponding to this ID, result is
    703      * set to bogus.</p>
    704      *
    705      * @param id the ID for which to retrieve the localized displayName.
    706      * @param result an output parameter to hold the display name.
    707      * @param locale the locale in which to localize the ID.
    708      * @return the modified result.
    709      */
    710     UnicodeString& getDisplayName(const UnicodeString& id, UnicodeString& result, const Locale& locale) const;
    711 
    712     /**
    713      * <p>Convenience override of getDisplayNames(const Locale&, const UnicodeString*) that
    714      * uses the current default Locale as the locale and NULL for
    715      * the matchID.</p>
    716      *
    717      * @param result a vector to hold the returned displayName/id StringPairs.
    718      * @param status the error code status.
    719      * @return the modified result vector.
    720      */
    721     UVector& getDisplayNames(UVector& result, UErrorCode& status) const;
    722 
    723     /**
    724      * <p>Convenience override of getDisplayNames(const Locale&, const UnicodeString*) that
    725      * uses NULL for the matchID.</p>
    726      *
    727      * @param result a vector to hold the returned displayName/id StringPairs.
    728      * @param locale the locale in which to localize the ID.
    729      * @param status the error code status.
    730      * @return the modified result vector.
    731      */
    732     UVector& getDisplayNames(UVector& result, const Locale& locale, UErrorCode& status) const;
    733 
    734     /**
    735      * <p>Return a snapshot of the mapping from display names to visible
    736      * IDs for this service.  This set will not change as factories
    737      * are added or removed, but the supported IDs will, so there is
    738      * no guarantee that all and only the IDs in the returned map will
    739      * be visible and supported by the service in subsequent calls,
    740      * nor is there any guarantee that the current display names match
    741      * those in the result.</p>
    742      *
    743      * <p>The names are returned as pointers to StringPairs, which
    744      * contain both the displayName and the corresponding ID.  The
    745      * caller owns the StringPairs.  Previous contents of result are
    746      * discarded before new elements, if any, are added.</p>
    747      *
    748      * <p>matchID is passed to createKey to create a key.  If the key
    749      * is not NULL, its isFallbackOf method is used to filter out IDs
    750      * that don't match the key or have it as a fallback.</p>
    751      *
    752      * @param result a vector to hold the returned displayName/id StringPairs.
    753      * @param locale the locale in which to localize the ID.
    754      * @param matchID an ID used to filter the result, or NULL if all IDs are desired.
    755      * @param status the error code status.
    756      * @return the result vector.  */
    757     UVector& getDisplayNames(UVector& result,
    758                              const Locale& locale,
    759                              const UnicodeString* matchID,
    760                              UErrorCode& status) const;
    761 
    762     /**
    763      * <p>A convenience override of registerInstance(UObject*, const UnicodeString&, UBool)
    764      * that defaults visible to TRUE.</p>
    765      *
    766      * @param objToAdopt the object to register and adopt.
    767      * @param id the ID to assign to this object.
    768      * @param status the error code status.
    769      * @return a registry key that can be passed to unregister to unregister
    770      * (and discard) this instance.
    771      */
    772     URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& id, UErrorCode& status);
    773 
    774     /**
    775      * <p>Register a service instance with the provided ID.  The ID will be
    776      * canonicalized.  The canonicalized ID will be returned by
    777      * getVisibleIDs if visible is TRUE.  The service instance will be adopted and
    778      * must not be modified subsequent to this call.</p>
    779      *
    780      * <p>This issues a serviceChanged notification to registered listeners.</p>
    781      *
    782      * <p>This implementation wraps the object using
    783      * createSimpleFactory, and calls registerFactory.</p>
    784      *
    785      * @param objToAdopt the object to register and adopt.
    786      * @param id the ID to assign to this object.
    787      * @param visible TRUE if getVisibleIDs is to return this ID.
    788      * @param status the error code status.
    789      * @return a registry key that can be passed to unregister() to unregister
    790      * (and discard) this instance.
    791      */
    792     virtual URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status);
    793 
    794     /**
    795      * <p>Register an ICUServiceFactory.  Returns a registry key that
    796      * can be used to unregister the factory.  The factory
    797      * must not be modified subsequent to this call.  The service owns
    798      * all registered factories. In case of an error, the factory is
    799      * deleted.</p>
    800      *
    801      * <p>This issues a serviceChanged notification to registered listeners.</p>
    802      *
    803      * <p>The default implementation accepts all factories.</p>
    804      *
    805      * @param factoryToAdopt the factory to register and adopt.
    806      * @param status the error code status.
    807      * @return a registry key that can be passed to unregister to unregister
    808      * (and discard) this factory.
    809      */
    810     virtual URegistryKey registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status);
    811 
    812     /**
    813      * <p>Unregister a factory using a registry key returned by
    814      * registerInstance or registerFactory.  After a successful call,
    815      * the factory will be removed from the service factory list and
    816      * deleted, and the key becomes invalid.</p>
    817      *
    818      * <p>This issues a serviceChanged notification to registered
    819      * listeners.</p>
    820      *
    821      * @param rkey the registry key.
    822      * @param status the error code status.
    823      * @return TRUE if the call successfully unregistered the factory.
    824      */
    825     virtual UBool unregister(URegistryKey rkey, UErrorCode& status);
    826 
    827     /**
    828      * </p>Reset the service to the default factories.  The factory
    829      * lock is acquired and then reInitializeFactories is called.</p>
    830      *
    831      * <p>This issues a serviceChanged notification to registered listeners.</p>
    832      */
    833     virtual void reset(void);
    834 
    835     /**
    836      * <p>Return TRUE if the service is in its default state.</p>
    837      *
    838      * <p>The default implementation returns TRUE if there are no
    839      * factories registered.</p>
    840      */
    841     virtual UBool isDefault(void) const;
    842 
    843     /**
    844      * <p>Create a key from an ID.  If ID is NULL, returns NULL.</p>
    845      *
    846      * <p>The default implementation creates an ICUServiceKey instance.
    847      * Subclasses can override to define more useful keys appropriate
    848      * to the factories they accept.</p>
    849      *
    850      * @param a pointer to the ID for which to create a default ICUServiceKey.
    851      * @param status the error code status.
    852      * @return the ICUServiceKey corresponding to ID, or NULL.
    853      */
    854     virtual ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const;
    855 
    856     /**
    857      * <p>Clone object so that caller can own the copy.  In ICU2.4, UObject doesn't define
    858      * clone, so we need an instance-aware method that knows how to do this.
    859      * This is public so factories can call it, but should really be protected.</p>
    860      *
    861      * @param instance the service instance to clone.
    862      * @return a clone of the passed-in instance, or NULL if cloning was unsuccessful.
    863      */
    864     virtual UObject* cloneInstance(UObject* instance) const = 0;
    865 
    866 
    867     /************************************************************************
    868      * Subclassing API
    869      */
    870 
    871  protected:
    872 
    873     /**
    874      * <p>Create a factory that wraps a single service object.  Called by registerInstance.</p>
    875      *
    876      * <p>The default implementation returns an instance of SimpleFactory.</p>
    877      *
    878      * @param instanceToAdopt the service instance to adopt.
    879      * @param id the ID to assign to this service instance.
    880      * @param visible if TRUE, the ID will be visible.
    881      * @param status the error code status.
    882      * @return an instance of ICUServiceFactory that maps this instance to the provided ID.
    883      */
    884     virtual ICUServiceFactory* createSimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status);
    885 
    886     /**
    887      * <p>Reinitialize the factory list to its default state.  After this call, isDefault()
    888      * must return TRUE.</p>
    889      *
    890      * <p>This issues a serviceChanged notification to registered listeners.</p>
    891      *
    892      * <p>The default implementation clears the factory list.
    893      * Subclasses can override to provide other default initialization
    894      * of the factory list.  Subclasses must not call this method
    895      * directly, since it must only be called while holding write
    896      * access to the factory list.</p>
    897      */
    898     virtual void reInitializeFactories(void);
    899 
    900     /**
    901      * <p>Default handler for this service if no factory in the factory list
    902      * handled the key passed to getKey.</p>
    903      *
    904      * <p>The default implementation returns NULL.</p>
    905      *
    906      * @param key the key.
    907      * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
    908      * @param status the error code status.
    909      * @return the service instance, or NULL.
    910      */
    911     virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const;
    912 
    913     /**
    914      * <p>Clear caches maintained by this service.</p>
    915      *
    916      * <p>Subclasses can override if they implement additional caches
    917      * that need to be cleared when the service changes.  Subclasses
    918      * should generally not call this method directly, as it must only
    919      * be called while synchronized on the factory lock.</p>
    920      */
    921     virtual void clearCaches(void);
    922 
    923     /**
    924      * <p>Return true if the listener is accepted.</p>
    925      *
    926      * <p>The default implementation accepts the listener if it is
    927      * a ServiceListener.  Subclasses can override this to accept
    928      * different listeners.</p>
    929      *
    930      * @param l the listener to test.
    931      * @return TRUE if the service accepts the listener.
    932      */
    933     virtual UBool acceptsListener(const EventListener& l) const;
    934 
    935     /**
    936      * <p>Notify the listener of a service change.</p>
    937      *
    938      * <p>The default implementation assumes a ServiceListener.
    939      * If acceptsListener has been overridden to accept different
    940      * listeners, this should be overridden as well.</p>
    941      *
    942      * @param l the listener to notify.
    943      */
    944     virtual void notifyListener(EventListener& l) const;
    945 
    946     /************************************************************************
    947      * Utilities for subclasses.
    948      */
    949 
    950     /**
    951      * <p>Clear only the service cache.</p>
    952      *
    953      * <p>This can be called by subclasses when a change affects the service
    954      * cache but not the ID caches, e.g., when the default locale changes
    955      * the resolution of IDs also changes, requiring the cache to be
    956      * flushed, but not the visible IDs themselves.</p>
    957      */
    958     void clearServiceCache(void);
    959 
    960     /**
    961      * <p>Return a map from visible IDs to factories.
    962      * This must only be called when the mutex is held.</p>
    963      *
    964      * @param status the error code status.
    965      * @return a Hashtable containing mappings from visible
    966      * IDs to factories.
    967      */
    968     const Hashtable* getVisibleIDMap(UErrorCode& status) const;
    969 
    970     /**
    971      * <p>Allow subclasses to read the time stamp.</p>
    972      *
    973      * @return the timestamp.
    974      */
    975     int32_t getTimestamp(void) const;
    976 
    977     /**
    978      * <p>Return the number of registered factories.</p>
    979      *
    980      * @return the number of factories registered at the time of the call.
    981      */
    982     int32_t countFactories(void) const;
    983 
    984 private:
    985 
    986     friend class ::ICUServiceTest; // give tests access to countFactories.
    987 };
    988 
    989 U_NAMESPACE_END
    990 
    991     /* UCONFIG_NO_SERVICE */
    992 #endif
    993 
    994     /* ICUSERV_H */
    995 #endif
    996 
    997