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