Line data Source code
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 0 : 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 0 : 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 :
|