serv.h 36 KB

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