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