• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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