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