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