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 and * 6 * others. All Rights Reserved. * 7 ******************************************************************************* 8 * 9 ******************************************************************************* 10 */ 11 #ifndef ICULSERV_H 12 #define ICULSERV_H 13 14 #include "unicode/utypes.h" 15 16 #if UCONFIG_NO_SERVICE 17 18 U_NAMESPACE_BEGIN 19 20 /* 21 * Allow the declaration of APIs with pointers to ICUService 22 * even when service is removed from the build. 23 */ 24 class ICULocaleService; 25 26 U_NAMESPACE_END 27 28 #else 29 30 #include "unicode/unistr.h" 31 #include "unicode/locid.h" 32 #include "unicode/strenum.h" 33 34 #include "hash.h" 35 #include "uvector.h" 36 37 #include "serv.h" 38 #include "locutil.h" 39 40 U_NAMESPACE_BEGIN 41 42 class ICULocaleService; 43 44 class LocaleKey; 45 class LocaleKeyFactory; 46 class SimpleLocaleKeyFactory; 47 class ServiceListener; 48 49 /* 50 ****************************************************************** 51 */ 52 53 /** 54 * A subclass of Key that implements a locale fallback mechanism. 55 * The first locale to search for is the locale provided by the 56 * client, and the fallback locale to search for is the current 57 * default locale. If a prefix is present, the currentDescriptor 58 * includes it before the locale proper, separated by "/". This 59 * is the default key instantiated by ICULocaleService.</p> 60 * 61 * <p>Canonicalization adjusts the locale string so that the 62 * section before the first understore is in lower case, and the rest 63 * is in upper case, with no trailing underscores.</p> 64 */ 65 66 class U_COMMON_API LocaleKey : public ICUServiceKey { 67 private: 68 int32_t _kind; 69 UnicodeString _primaryID; 70 UnicodeString _fallbackID; 71 UnicodeString _currentID; 72 73 public: 74 enum { 75 KIND_ANY = -1 76 }; 77 78 /** 79 * Create a LocaleKey with canonical primary and fallback IDs. 80 */ 81 static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, 82 const UnicodeString* canonicalFallbackID, 83 UErrorCode& status); 84 85 /** 86 * Create a LocaleKey with canonical primary and fallback IDs. 87 */ 88 static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, 89 const UnicodeString* canonicalFallbackID, 90 int32_t kind, 91 UErrorCode& status); 92 93 protected: 94 /** 95 * PrimaryID is the user's requested locale string, 96 * canonicalPrimaryID is this string in canonical form, 97 * fallbackID is the current default locale's string in 98 * canonical form. 99 */ 100 LocaleKey(const UnicodeString& primaryID, 101 const UnicodeString& canonicalPrimaryID, 102 const UnicodeString* canonicalFallbackID, 103 int32_t kind); 104 105 public: 106 /** 107 * Append the prefix associated with the kind, or nothing if the kind is KIND_ANY. 108 */ 109 virtual UnicodeString& prefix(UnicodeString& result) const; 110 111 /** 112 * Return the kind code associated with this key. 113 */ 114 virtual int32_t kind() const; 115 116 /** 117 * Return the canonicalID. 118 */ 119 virtual UnicodeString& canonicalID(UnicodeString& result) const; 120 121 /** 122 * Return the currentID. 123 */ 124 virtual UnicodeString& currentID(UnicodeString& result) const; 125 126 /** 127 * Return the (canonical) current descriptor, or null if no current id. 128 */ 129 virtual UnicodeString& currentDescriptor(UnicodeString& result) const; 130 131 /** 132 * Convenience method to return the locale corresponding to the (canonical) original ID. 133 */ 134 virtual Locale& canonicalLocale(Locale& result) const; 135 136 /** 137 * Convenience method to return the locale corresponding to the (canonical) current ID. 138 */ 139 virtual Locale& currentLocale(Locale& result) const; 140 141 /** 142 * If the key has a fallback, modify the key and return true, 143 * otherwise return false.</p> 144 * 145 * <p>First falls back through the primary ID, then through 146 * the fallbackID. The final fallback is the empty string, 147 * unless the primary id was the empty string, in which case 148 * there is no fallback. 149 */ 150 virtual UBool fallback(); 151 152 /** 153 * Return true if a key created from id matches, or would eventually 154 * fallback to match, the canonical ID of this key. 155 */ 156 virtual UBool isFallbackOf(const UnicodeString& id) const; 157 158 public: 159 /** 160 * UObject boilerplate. 161 */ 162 static UClassID U_EXPORT2 getStaticClassID(); 163 164 virtual UClassID getDynamicClassID() const; 165 166 /** 167 * Destructor. 168 */ 169 virtual ~LocaleKey(); 170 171 #ifdef SERVICE_DEBUG 172 public: 173 virtual UnicodeString& debug(UnicodeString& result) const; 174 virtual UnicodeString& debugClass(UnicodeString& result) const; 175 #endif 176 177 }; 178 179 /* 180 ****************************************************************** 181 */ 182 183 /** 184 * A subclass of ICUServiceFactory that uses LocaleKeys, and is able to 185 * 'cover' more specific locales with more general locales that it 186 * supports. 187 * 188 * <p>Coverage may be either of the values VISIBLE or INVISIBLE. 189 * 190 * <p>'Visible' indicates that the specific locale(s) supported by 191 * the factory are registered in getSupportedIDs, 'Invisible' 192 * indicates that they are not. 193 * 194 * <p>Localization of visible ids is handled 195 * by the handling factory, regardless of kind. 196 */ 197 class U_COMMON_API LocaleKeyFactory : public ICUServiceFactory { 198 protected: 199 const UnicodeString _name; 200 const int32_t _coverage; 201 202 public: 203 enum { 204 /** 205 * Coverage value indicating that the factory makes 206 * its locales visible, and does not cover more specific 207 * locales. 208 */ 209 VISIBLE = 0, 210 211 /** 212 * Coverage value indicating that the factory does not make 213 * its locales visible, and does not cover more specific 214 * locales. 215 */ 216 INVISIBLE = 1 217 }; 218 219 /** 220 * Destructor. 221 */ 222 virtual ~LocaleKeyFactory(); 223 224 protected: 225 /** 226 * Constructor used by subclasses. 227 */ 228 LocaleKeyFactory(int32_t coverage); 229 230 /** 231 * Constructor used by subclasses. 232 */ 233 LocaleKeyFactory(int32_t coverage, const UnicodeString& name); 234 235 /** 236 * Implement superclass abstract method. This checks the currentID of 237 * the key against the supported IDs, and passes the canonicalLocale and 238 * kind off to handleCreate (which subclasses must implement). 239 */ 240 public: 241 virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const; 242 243 protected: 244 virtual UBool handlesKey(const ICUServiceKey& key, UErrorCode& status) const; 245 246 public: 247 /** 248 * Override of superclass method. This adjusts the result based 249 * on the coverage rule for this factory. 250 */ 251 virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const; 252 253 /** 254 * Return a localized name for the locale represented by id. 255 */ 256 virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const; 257 258 protected: 259 /** 260 * Utility method used by create(ICUServiceKey, ICUService). Subclasses can implement 261 * this instead of create. The default returns NULL. 262 */ 263 virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const; 264 265 /** 266 * Return true if this id is one the factory supports (visible or 267 * otherwise). 268 */ 269 // virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const; 270 271 /** 272 * Return the set of ids that this factory supports (visible or 273 * otherwise). This can be called often and might need to be 274 * cached if it is expensive to create. 275 */ 276 virtual const Hashtable* getSupportedIDs(UErrorCode& status) const; 277 278 public: 279 /** 280 * UObject boilerplate. 281 */ 282 static UClassID U_EXPORT2 getStaticClassID(); 283 284 virtual UClassID getDynamicClassID() const; 285 286 #ifdef SERVICE_DEBUG 287 public: 288 virtual UnicodeString& debug(UnicodeString& result) const; 289 virtual UnicodeString& debugClass(UnicodeString& result) const; 290 #endif 291 292 }; 293 294 /* 295 ****************************************************************** 296 */ 297 298 /** 299 * A LocaleKeyFactory that just returns a single object for a kind/locale. 300 */ 301 302 class U_COMMON_API SimpleLocaleKeyFactory : public LocaleKeyFactory { 303 private: 304 UObject* _obj; 305 UnicodeString _id; 306 const int32_t _kind; 307 308 public: 309 SimpleLocaleKeyFactory(UObject* objToAdopt, 310 const UnicodeString& locale, 311 int32_t kind, 312 int32_t coverage); 313 314 SimpleLocaleKeyFactory(UObject* objToAdopt, 315 const Locale& locale, 316 int32_t kind, 317 int32_t coverage); 318 319 /** 320 * Destructor. 321 */ 322 virtual ~SimpleLocaleKeyFactory(); 323 324 /** 325 * Override of superclass method. Returns the service object if kind/locale match. Service is not used. 326 */ 327 virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const; 328 329 /** 330 * Override of superclass method. This adjusts the result based 331 * on the coverage rule for this factory. 332 */ 333 virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const; 334 335 protected: 336 /** 337 * Return true if this id is equal to the locale name. 338 */ 339 //virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const; 340 341 342 public: 343 /** 344 * UObject boilerplate. 345 */ 346 static UClassID U_EXPORT2 getStaticClassID(); 347 348 virtual UClassID getDynamicClassID() const; 349 350 #ifdef SERVICE_DEBUG 351 public: 352 virtual UnicodeString& debug(UnicodeString& result) const; 353 virtual UnicodeString& debugClass(UnicodeString& result) const; 354 #endif 355 356 }; 357 358 /* 359 ****************************************************************** 360 */ 361 362 /** 363 * A LocaleKeyFactory that creates a service based on the ICU locale data. 364 * This is a base class for most ICU factories. Subclasses instantiate it 365 * with a constructor that takes a bundle name, which determines the supported 366 * IDs. Subclasses then override handleCreate to create the actual service 367 * object. The default implementation returns a resource bundle. 368 */ 369 class U_COMMON_API ICUResourceBundleFactory : public LocaleKeyFactory 370 { 371 protected: 372 UnicodeString _bundleName; 373 374 public: 375 /** 376 * Convenience constructor that uses the main ICU bundle name. 377 */ 378 ICUResourceBundleFactory(); 379 380 /** 381 * A service factory based on ICU resource data in resources with 382 * the given name. This should be a 'path' that can be passed to 383 * ures_openAvailableLocales, such as U_ICUDATA or U_ICUDATA_COLL. 384 * The empty string is equivalent to U_ICUDATA. 385 */ 386 ICUResourceBundleFactory(const UnicodeString& bundleName); 387 388 /** 389 * Destructor 390 */ 391 virtual ~ICUResourceBundleFactory(); 392 393 protected: 394 /** 395 * Return the supported IDs. This is the set of all locale names in ICULocaleData. 396 */ 397 virtual const Hashtable* getSupportedIDs(UErrorCode& status) const; 398 399 /** 400 * Create the service. The default implementation returns the resource bundle 401 * for the locale, ignoring kind, and service. 402 */ 403 virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const; 404 405 public: 406 /** 407 * UObject boilerplate. 408 */ 409 static UClassID U_EXPORT2 getStaticClassID(); 410 virtual UClassID getDynamicClassID() const; 411 412 413 #ifdef SERVICE_DEBUG 414 public: 415 virtual UnicodeString& debug(UnicodeString& result) const; 416 virtual UnicodeString& debugClass(UnicodeString& result) const; 417 #endif 418 419 }; 420 421 /* 422 ****************************************************************** 423 */ 424 425 class U_COMMON_API ICULocaleService : public ICUService 426 { 427 private: 428 Locale fallbackLocale; 429 UnicodeString fallbackLocaleName; 430 431 public: 432 /** 433 * Construct an ICULocaleService. 434 */ 435 ICULocaleService(); 436 437 /** 438 * Construct an ICULocaleService with a name (useful for debugging). 439 */ 440 ICULocaleService(const UnicodeString& name); 441 442 /** 443 * Destructor. 444 */ 445 virtual ~ICULocaleService(); 446 447 #if 0 448 // redeclare because of overload resolution rules? 449 // no, causes ambiguities since both UnicodeString and Locale have constructors that take a const char* 450 // need some compiler flag to remove warnings 451 UObject* get(const UnicodeString& descriptor, UErrorCode& status) const { 452 return ICUService::get(descriptor, status); 453 } 454 455 UObject* get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const { 456 return ICUService::get(descriptor, actualReturn, status); 457 } 458 #endif 459 460 /** 461 * Convenience override for callers using locales. This calls 462 * get(Locale, int, Locale[]) with KIND_ANY for kind and null for 463 * actualReturn. 464 */ 465 UObject* get(const Locale& locale, UErrorCode& status) const; 466 467 /** 468 * Convenience override for callers using locales. This calls 469 * get(Locale, int, Locale[]) with a null actualReturn. 470 */ 471 UObject* get(const Locale& locale, int32_t kind, UErrorCode& status) const; 472 473 /** 474 * Convenience override for callers using locales. This calls 475 * get(Locale, String, Locale[]) with a null kind. 476 */ 477 UObject* get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const; 478 479 /** 480 * Convenience override for callers using locales. This uses 481 * createKey(Locale.toString(), kind) to create a key, calls getKey, and then 482 * if actualReturn is not null, returns the actualResult from 483 * getKey (stripping any prefix) into a Locale. 484 */ 485 UObject* get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const; 486 487 /** 488 * Convenience override for callers using locales. This calls 489 * registerObject(Object, Locale, int32_t kind, int coverage) 490 * passing KIND_ANY for the kind, and VISIBLE for the coverage. 491 */ 492 virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status); 493 494 /** 495 * Convenience function for callers using locales. This calls 496 * registerObject(Object, Locale, int kind, int coverage) 497 * passing VISIBLE for the coverage. 498 */ 499 virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status); 500 501 /** 502 * Convenience function for callers using locales. This instantiates 503 * a SimpleLocaleKeyFactory, and registers the factory. 504 */ 505 virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status); 506 507 508 /** 509 * (Stop compiler from complaining about hidden overrides.) 510 * Since both UnicodeString and Locale have constructors that take const char*, adding a public 511 * method that takes UnicodeString causes ambiguity at call sites that use const char*. 512 * We really need a flag that is understood by all compilers that will suppress the warning about 513 * hidden overrides. 514 */ 515 virtual URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status); 516 517 /** 518 * Convenience method for callers using locales. This returns the standard 519 * service ID enumeration. 520 */ 521 virtual StringEnumeration* getAvailableLocales(void) const; 522 523 protected: 524 525 /** 526 * Return the name of the current fallback locale. If it has changed since this was 527 * last accessed, the service cache is cleared. 528 */ 529 const UnicodeString& validateFallbackLocale() const; 530 531 /** 532 * Override superclass createKey method. 533 */ 534 virtual ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const; 535 536 /** 537 * Additional createKey that takes a kind. 538 */ 539 virtual ICUServiceKey* createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const; 540 541 friend class ServiceEnumeration; 542 }; 543 544 U_NAMESPACE_END 545 546 /* UCONFIG_NO_SERVICE */ 547 #endif 548 549 /* ICULSERV_H */ 550 #endif 551 552