]>
Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
b75a7d8f A |
3 | /** |
4 | ******************************************************************************* | |
4388f060 | 5 | * Copyright (C) 2001-2011, International Business Machines Corporation. * |
b75a7d8f A |
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 | ||
b75a7d8f | 29 | #include "unicode/unistr.h" |
b75a7d8f | 30 | #include "unicode/locid.h" |
73c04bcf | 31 | #include "unicode/umisc.h" |
b75a7d8f A |
32 | |
33 | #include "hash.h" | |
34 | #include "uvector.h" | |
73c04bcf | 35 | #include "servnotf.h" |
b75a7d8f A |
36 | |
37 | class ICUServiceTest; | |
38 | ||
39 | U_NAMESPACE_BEGIN | |
40 | ||
41 | class ICUServiceKey; | |
42 | class ICUServiceFactory; | |
43 | class SimpleFactory; | |
44 | class ServiceListener; | |
b75a7d8f A |
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 | ||
374ca955 | 185 | public: |
b75a7d8f A |
186 | /** |
187 | * UObject RTTI boilerplate. | |
188 | */ | |
374ca955 | 189 | static UClassID U_EXPORT2 getStaticClassID(); |
b75a7d8f A |
190 | |
191 | /** | |
192 | * UObject RTTI boilerplate. | |
193 | */ | |
374ca955 | 194 | virtual UClassID getDynamicClassID() const; |
b75a7d8f A |
195 | |
196 | #ifdef SERVICE_DEBUG | |
197 | public: | |
198 | virtual UnicodeString& debug(UnicodeString& result) const; | |
199 | virtual UnicodeString& debugClass(UnicodeString& result) const; | |
200 | #endif | |
201 | ||
b75a7d8f A |
202 | }; |
203 | ||
204 | /******************************************************************* | |
205 | * ICUServiceFactory | |
206 | */ | |
207 | ||
208 | /** | |
73c04bcf | 209 | * <p>An implementing ICUServiceFactory generates the service objects maintained by the |
b75a7d8f A |
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: | |
4388f060 | 216 | virtual ~ICUServiceFactory(); |
b75a7d8f A |
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 | |
73c04bcf | 258 | * not visible, sets result to bogus. If the |
b75a7d8f | 259 | * incoming result is bogus, it remains bogus. Result is returned as a |
73c04bcf A |
260 | * convenience. Results are not defined if id is not one supported by this |
261 | * factory.</p> | |
b75a7d8f A |
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 | */ | |
73c04bcf | 318 | virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const; |
b75a7d8f A |
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 | */ | |
73c04bcf | 327 | virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const; |
b75a7d8f A |
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 | */ | |
73c04bcf | 339 | virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const; |
b75a7d8f | 340 | |
73c04bcf | 341 | public: |
b75a7d8f A |
342 | /** |
343 | * UObject RTTI boilerplate. | |
344 | */ | |
374ca955 | 345 | static UClassID U_EXPORT2 getStaticClassID(); |
b75a7d8f A |
346 | |
347 | /** | |
348 | * UObject RTTI boilerplate. | |
349 | */ | |
374ca955 | 350 | virtual UClassID getDynamicClassID() const; |
b75a7d8f A |
351 | |
352 | #ifdef SERVICE_DEBUG | |
353 | public: | |
354 | virtual UnicodeString& debug(UnicodeString& toAppendTo) const; | |
355 | virtual UnicodeString& debugClass(UnicodeString& toAppendTo) const; | |
356 | #endif | |
357 | ||
b75a7d8f A |
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: | |
4388f060 A |
373 | virtual ~ServiceListener(); |
374 | ||
b75a7d8f A |
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 | */ | |
374ca955 | 388 | static UClassID U_EXPORT2 getStaticClassID(); |
b75a7d8f A |
389 | |
390 | /** | |
391 | * UObject RTTI boilerplate. | |
392 | */ | |
374ca955 | 393 | virtual UClassID getDynamicClassID() const; |
b75a7d8f | 394 | |
b75a7d8f A |
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 | ||
b75a7d8f A |
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 | ||
b75a7d8f A |
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> | |
374ca955 A |
633 | * |
634 | * <p>Subclasses can override this method to further customize the | |
635 | * result before returning it. | |
b75a7d8f A |
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 | |
374ca955 | 648 | * should not call it directly, but call through one of the other get functions.</p> |
b75a7d8f A |
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 |