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