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