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