1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 2004-2016, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 */ 10 11 package ohos.global.icu.util; 12 13 import java.nio.ByteBuffer; 14 import java.util.Collections; 15 import java.util.Enumeration; 16 import java.util.HashMap; 17 import java.util.Locale; 18 import java.util.Map; 19 import java.util.MissingResourceException; 20 import java.util.ResourceBundle; 21 import java.util.Set; 22 import java.util.TreeSet; 23 import java.util.concurrent.ConcurrentHashMap; 24 25 import ohos.global.icu.impl.ICUData; 26 import ohos.global.icu.impl.ICUResourceBundle; 27 import ohos.global.icu.impl.ICUResourceBundleReader; 28 import ohos.global.icu.impl.ResourceBundleWrapper; 29 30 /** 31 * <strong>[icu enhancement]</strong> ICU's replacement for {@link java.util.ResourceBundle}. Methods, fields, and other functionality specific to ICU are labeled '<strong>[icu]</strong>'. 32 * 33 * <p>A class representing a collection of resource information pertaining to a given 34 * locale. A resource bundle provides a way of accessing locale- specific information in a 35 * data file. You create a resource bundle that manages the resources for a given locale 36 * and then ask it for individual resources. 37 * 38 * <p>In ResourceBundle, an object is created and the sub-items are fetched using the 39 * getString and getObject methods. In UResourceBundle, each individual element of a 40 * resource is a resource by itself. 41 * 42 * <p>Resource bundles in ICU are currently defined using text files that conform to the 43 * following <a 44 * href="http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt">BNF 45 * definition</a>. More on resource bundle concepts and syntax can be found in the <a 46 * href="http://www.icu-project.org/userguide/ResourceManagement.html">Users Guide</a>. 47 * 48 * <p>The packaging of ICU *.res files can be of two types 49 * ICU4C: 50 * <pre> 51 * root.res 52 * | 53 * -------- 54 * | | 55 * fr.res en.res 56 * | 57 * -------- 58 * | | 59 * fr_CA.res fr_FR.res 60 * </pre> 61 * JAVA/JDK: 62 * <pre> 63 * LocaleElements.res 64 * | 65 * ------------------- 66 * | | 67 * LocaleElements_fr.res LocaleElements_en.res 68 * | 69 * --------------------------- 70 * | | 71 * LocaleElements_fr_CA.res LocaleElements_fr_FR.res 72 * </pre> 73 * 74 * Depending on the organization of your resources, the syntax to getBundleInstance will 75 * change. To open ICU style organization use: 76 * 77 * <pre> 78 * UResourceBundle bundle = 79 * UResourceBundle.getBundleInstance("com/mycompany/resources", 80 * "en_US", myClassLoader); 81 * </pre> 82 * To open Java/JDK style organization use: 83 * <pre> 84 * UResourceBundle bundle = 85 * UResourceBundle.getBundleInstance("com.mycompany.resources.LocaleElements", 86 * "en_US", myClassLoader); 87 * </pre> 88 * 89 * <p>Note: Please use pass a class loader for loading non-ICU resources. Java security does not 90 * allow loading of resources across jar files. You must provide your class loader 91 * to load the resources 92 93 * @author ram 94 * @hide exposed on OHOS 95 */ 96 public abstract class UResourceBundle extends ResourceBundle { 97 98 99 /** 100 * <strong>[icu]</strong> Creates a resource bundle using the specified base name and locale. 101 * ICU_DATA_CLASS is used as the default root. 102 * @param baseName string containing the name of the data package. 103 * If null the default ICU package name is used. 104 * @param localeName the locale for which a resource bundle is desired 105 * @throws MissingResourceException If no resource bundle for the specified base name 106 * can be found 107 * @return a resource bundle for the given base name and locale 108 */ getBundleInstance(String baseName, String localeName)109 public static UResourceBundle getBundleInstance(String baseName, String localeName){ 110 return getBundleInstance(baseName, localeName, ICUResourceBundle.ICU_DATA_CLASS_LOADER, 111 false); 112 } 113 114 /** 115 * <strong>[icu]</strong> Creates a resource bundle using the specified base name, locale, and class root. 116 * 117 * @param baseName string containing the name of the data package. 118 * If null the default ICU package name is used. 119 * @param localeName the locale for which a resource bundle is desired 120 * @param root the class object from which to load the resource bundle 121 * @throws MissingResourceException If no resource bundle for the specified base name 122 * can be found 123 * @return a resource bundle for the given base name and locale 124 */ getBundleInstance(String baseName, String localeName, ClassLoader root)125 public static UResourceBundle getBundleInstance(String baseName, String localeName, 126 ClassLoader root){ 127 return getBundleInstance(baseName, localeName, root, false); 128 } 129 130 /** 131 * <strong>[icu]</strong> Creates a resource bundle using the specified base name, locale, and class 132 * root. 133 * 134 * @param baseName string containing the name of the data package. 135 * If null the default ICU package name is used. 136 * @param localeName the locale for which a resource bundle is desired 137 * @param root the class object from which to load the resource bundle 138 * @param disableFallback Option to disable locale inheritence. 139 * If true the fallback chain will not be built. 140 * @throws MissingResourceException 141 * if no resource bundle for the specified base name can be found 142 * @return a resource bundle for the given base name and locale 143 * 144 */ getBundleInstance(String baseName, String localeName, ClassLoader root, boolean disableFallback)145 protected static UResourceBundle getBundleInstance(String baseName, String localeName, 146 ClassLoader root, boolean disableFallback) { 147 return instantiateBundle(baseName, localeName, root, disableFallback); 148 } 149 150 /** 151 * <strong>[icu]</strong> Sole constructor. (For invocation by subclass constructors, typically 152 * implicit.) This is public for compatibility with Java, whose compiler 153 * will generate public default constructors for an abstract class. 154 */ UResourceBundle()155 public UResourceBundle() { 156 } 157 158 /** 159 * <strong>[icu]</strong> Creates a UResourceBundle for the locale specified, from which users can extract 160 * resources by using their corresponding keys. 161 * @param locale specifies the locale for which we want to open the resource. 162 * If null the bundle for default locale is opened. 163 * @return a resource bundle for the given locale 164 */ getBundleInstance(ULocale locale)165 public static UResourceBundle getBundleInstance(ULocale locale) { 166 if (locale==null) { 167 locale = ULocale.getDefault(); 168 } 169 return getBundleInstance(ICUData.ICU_BASE_NAME, locale.getBaseName(), 170 ICUResourceBundle.ICU_DATA_CLASS_LOADER, false); 171 } 172 173 /** 174 * <strong>[icu]</strong> Creates a UResourceBundle for the default locale and specified base name, 175 * from which users can extract resources by using their corresponding keys. 176 * @param baseName string containing the name of the data package. 177 * If null the default ICU package name is used. 178 * @return a resource bundle for the given base name and default locale 179 */ getBundleInstance(String baseName)180 public static UResourceBundle getBundleInstance(String baseName) { 181 if (baseName == null) { 182 baseName = ICUData.ICU_BASE_NAME; 183 } 184 ULocale uloc = ULocale.getDefault(); 185 return getBundleInstance(baseName, uloc.getBaseName(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, 186 false); 187 } 188 189 /** 190 * <strong>[icu]</strong> Creates a UResourceBundle for the specified locale and specified base name, 191 * from which users can extract resources by using their corresponding keys. 192 * @param baseName string containing the name of the data package. 193 * If null the default ICU package name is used. 194 * @param locale specifies the locale for which we want to open the resource. 195 * If null the bundle for default locale is opened. 196 * @return a resource bundle for the given base name and locale 197 */ 198 getBundleInstance(String baseName, Locale locale)199 public static UResourceBundle getBundleInstance(String baseName, Locale locale) { 200 if (baseName == null) { 201 baseName = ICUData.ICU_BASE_NAME; 202 } 203 ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale); 204 205 return getBundleInstance(baseName, uloc.getBaseName(), 206 ICUResourceBundle.ICU_DATA_CLASS_LOADER, false); 207 } 208 209 /** 210 * <strong>[icu]</strong> Creates a UResourceBundle, from which users can extract resources by using 211 * their corresponding keys. 212 * @param baseName string containing the name of the data package. 213 * If null the default ICU package name is used. 214 * @param locale specifies the locale for which we want to open the resource. 215 * If null the bundle for default locale is opened. 216 * @return a resource bundle for the given base name and locale 217 */ getBundleInstance(String baseName, ULocale locale)218 public static UResourceBundle getBundleInstance(String baseName, ULocale locale) { 219 if (baseName == null) { 220 baseName = ICUData.ICU_BASE_NAME; 221 } 222 if (locale == null) { 223 locale = ULocale.getDefault(); 224 } 225 return getBundleInstance(baseName, locale.getBaseName(), 226 ICUResourceBundle.ICU_DATA_CLASS_LOADER, false); 227 } 228 229 /** 230 * <strong>[icu]</strong> Creates a UResourceBundle for the specified locale and specified base name, 231 * from which users can extract resources by using their corresponding keys. 232 * @param baseName string containing the name of the data package. 233 * If null the default ICU package name is used. 234 * @param locale specifies the locale for which we want to open the resource. 235 * If null the bundle for default locale is opened. 236 * @param loader the loader to use 237 * @return a resource bundle for the given base name and locale 238 */ getBundleInstance(String baseName, Locale locale, ClassLoader loader)239 public static UResourceBundle getBundleInstance(String baseName, Locale locale, 240 ClassLoader loader) { 241 if (baseName == null) { 242 baseName = ICUData.ICU_BASE_NAME; 243 } 244 ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale); 245 return getBundleInstance(baseName, uloc.getBaseName(), loader, false); 246 } 247 248 /** 249 * <strong>[icu]</strong> Creates a UResourceBundle, from which users can extract resources by using 250 * their corresponding keys.<br><br> 251 * Note: Please use this API for loading non-ICU resources. Java security does not 252 * allow loading of resources across jar files. You must provide your class loader 253 * to load the resources 254 * @param baseName string containing the name of the data package. 255 * If null the default ICU package name is used. 256 * @param locale specifies the locale for which we want to open the resource. 257 * If null the bundle for default locale is opened. 258 * @param loader the loader to use 259 * @return a resource bundle for the given base name and locale 260 */ getBundleInstance(String baseName, ULocale locale, ClassLoader loader)261 public static UResourceBundle getBundleInstance(String baseName, ULocale locale, 262 ClassLoader loader) { 263 if (baseName == null) { 264 baseName = ICUData.ICU_BASE_NAME; 265 } 266 if (locale == null) { 267 locale = ULocale.getDefault(); 268 } 269 return getBundleInstance(baseName, locale.getBaseName(), loader, false); 270 } 271 272 /** 273 * <strong>[icu]</strong> Returns the RFC 3066 conformant locale id of this resource bundle. 274 * This method can be used after a call to getBundleInstance() to 275 * determine whether the resource bundle returned really 276 * corresponds to the requested locale or is a fallback. 277 * 278 * @return the locale of this resource bundle 279 */ getULocale()280 public abstract ULocale getULocale(); 281 282 /** 283 * <strong>[icu]</strong> Returns the localeID 284 * @return The string representation of the localeID 285 */ getLocaleID()286 protected abstract String getLocaleID(); 287 288 /** 289 * <strong>[icu]</strong> Returns the base name of the resource bundle 290 * @return The string representation of the base name 291 */ getBaseName()292 protected abstract String getBaseName(); 293 294 /** 295 * <strong>[icu]</strong> Returns the parent bundle 296 * @return The parent bundle 297 */ getParent()298 protected abstract UResourceBundle getParent(); 299 300 301 /** 302 * Returns the locale of this bundle 303 * @return the locale of this resource bundle 304 */ 305 @Override getLocale()306 public Locale getLocale(){ 307 return getULocale().toLocale(); 308 } 309 310 private enum RootType { MISSING, ICU, JAVA } 311 312 private static Map<String, RootType> ROOT_CACHE = new ConcurrentHashMap<String, RootType>(); 313 getRootType(String baseName, ClassLoader root)314 private static RootType getRootType(String baseName, ClassLoader root) { 315 RootType rootType = ROOT_CACHE.get(baseName); 316 317 if (rootType == null) { 318 String rootLocale = (baseName.indexOf('.')==-1) ? "root" : ""; 319 try{ 320 ICUResourceBundle.getBundleInstance(baseName, rootLocale, root, true); 321 rootType = RootType.ICU; 322 }catch(MissingResourceException ex){ 323 try{ 324 ResourceBundleWrapper.getBundleInstance(baseName, rootLocale, root, true); 325 rootType = RootType.JAVA; 326 }catch(MissingResourceException e){ 327 //throw away the exception 328 rootType = RootType.MISSING; 329 } 330 } 331 332 ROOT_CACHE.put(baseName, rootType); 333 } 334 335 return rootType; 336 } 337 setRootType(String baseName, RootType rootType)338 private static void setRootType(String baseName, RootType rootType) { 339 ROOT_CACHE.put(baseName, rootType); 340 } 341 342 /** 343 * <strong>[icu]</strong> Loads a new resource bundle for the given base name, locale and class loader. 344 * Optionally will disable loading of fallback bundles. 345 * @param baseName string containing the name of the data package. 346 * If null the default ICU package name is used. 347 * @param localeName the locale for which a resource bundle is desired 348 * @param root the class object from which to load the resource bundle 349 * @param disableFallback disables loading of fallback lookup chain 350 * @throws MissingResourceException If no resource bundle for the specified base name 351 * can be found 352 * @return a resource bundle for the given base name and locale 353 */ instantiateBundle(String baseName, String localeName, ClassLoader root, boolean disableFallback)354 protected static UResourceBundle instantiateBundle(String baseName, String localeName, 355 ClassLoader root, boolean disableFallback) { 356 RootType rootType = getRootType(baseName, root); 357 358 switch (rootType) { 359 case ICU: 360 return ICUResourceBundle.getBundleInstance(baseName, localeName, root, disableFallback); 361 362 case JAVA: 363 return ResourceBundleWrapper.getBundleInstance(baseName, localeName, root, 364 disableFallback); 365 366 case MISSING: 367 default: 368 UResourceBundle b; 369 try{ 370 b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, 371 disableFallback); 372 setRootType(baseName, RootType.ICU); 373 }catch(MissingResourceException ex){ 374 b = ResourceBundleWrapper.getBundleInstance(baseName, localeName, root, 375 disableFallback); 376 setRootType(baseName, RootType.JAVA); 377 } 378 return b; 379 } 380 } 381 382 /** 383 * <strong>[icu]</strong> Returns a binary data item from a binary resource, as a read-only ByteBuffer. 384 * 385 * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL 386 * file. 387 * @see #getIntVector 388 * @see #getInt 389 * @throws MissingResourceException If no resource bundle can be found. 390 * @throws UResourceTypeMismatchException If the resource has a type mismatch. 391 */ getBinary()392 public ByteBuffer getBinary() { 393 throw new UResourceTypeMismatchException(""); 394 } 395 396 /** 397 * Returns a string from a string resource type 398 * 399 * @return a string 400 * @see #getBinary() 401 * @see #getIntVector 402 * @see #getInt 403 * @throws MissingResourceException If resource bundle is missing. 404 * @throws UResourceTypeMismatchException If resource bundle has a type mismatch. 405 */ getString()406 public String getString() { 407 throw new UResourceTypeMismatchException(""); 408 } 409 410 /** 411 * Returns a string array from a array resource type 412 * 413 * @return a string 414 * @see #getString() 415 * @see #getIntVector 416 * @throws MissingResourceException If resource bundle is missing. 417 * @throws UResourceTypeMismatchException If resource bundle has a type mismatch. 418 */ getStringArray()419 public String[] getStringArray() { 420 throw new UResourceTypeMismatchException(""); 421 } 422 423 /** 424 * <strong>[icu]</strong> Returns a binary data from a binary resource, as a byte array with a copy 425 * of the bytes from the resource bundle. 426 * 427 * @param ba The byte array to write the bytes to. A null variable is OK. 428 * @return an array of bytes containing the binary data from the resource. 429 * @see #getIntVector 430 * @see #getInt 431 * @throws MissingResourceException If resource bundle is missing. 432 * @throws UResourceTypeMismatchException If resource bundle has a type mismatch. 433 */ getBinary(byte[] ba)434 public byte[] getBinary(byte[] ba) { 435 throw new UResourceTypeMismatchException(""); 436 } 437 438 /** 439 * <strong>[icu]</strong> Returns a 32 bit integer array from a resource. 440 * 441 * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file. 442 * @see #getBinary() 443 * @see #getInt 444 * @throws MissingResourceException If resource bundle is missing. 445 * @throws UResourceTypeMismatchException If resource bundle has a type mismatch. 446 */ getIntVector()447 public int[] getIntVector() { 448 throw new UResourceTypeMismatchException(""); 449 } 450 451 /** 452 * <strong>[icu]</strong> Returns a signed integer from a resource. 453 * 454 * @return an integer value 455 * @see #getIntVector 456 * @see #getBinary() 457 * @throws MissingResourceException If resource bundle is missing. 458 * @throws UResourceTypeMismatchException If resource bundle type mismatch. 459 */ getInt()460 public int getInt() { 461 throw new UResourceTypeMismatchException(""); 462 } 463 464 /** 465 * <strong>[icu]</strong> Returns a unsigned integer from a resource. 466 * This integer is originally 28 bit and the sign gets propagated. 467 * 468 * @return an integer value 469 * @see #getIntVector 470 * @see #getBinary() 471 * @throws MissingResourceException If resource bundle is missing. 472 * @throws UResourceTypeMismatchException If resource bundle type mismatch. 473 */ getUInt()474 public int getUInt() { 475 throw new UResourceTypeMismatchException(""); 476 } 477 478 /** 479 * <strong>[icu]</strong> Returns a resource in a given resource that has a given key. 480 * 481 * @param aKey a key associated with the wanted resource 482 * @return a resource bundle object representing the resource 483 * @throws MissingResourceException If resource bundle is missing. 484 */ get(String aKey)485 public UResourceBundle get(String aKey) { 486 UResourceBundle obj = findTopLevel(aKey); 487 if (obj == null) { 488 String fullName = ICUResourceBundleReader.getFullName(getBaseName(), getLocaleID()); 489 throw new MissingResourceException( 490 "Can't find resource for bundle " + fullName + ", key " 491 + aKey, this.getClass().getName(), aKey); 492 } 493 return obj; 494 } 495 496 /** 497 * Returns a resource in a given resource that has a given key, or null if the 498 * resource is not found. 499 * 500 * @param aKey the key associated with the wanted resource 501 * @return the resource, or null 502 * @see #get(String) 503 * @deprecated This API is ICU internal only. 504 * @hide draft / provisional / internal are hidden on OHOS 505 */ 506 @Deprecated findTopLevel(String aKey)507 protected UResourceBundle findTopLevel(String aKey) { 508 // NOTE: this only works for top-level resources. For resources at lower 509 // levels, it fails when you fall back to the parent, since you're now 510 // looking at root resources, not at the corresponding nested resource. 511 for (UResourceBundle res = this; res != null; res = res.getParent()) { 512 UResourceBundle obj = res.handleGet(aKey, null, this); 513 if (obj != null) { 514 return obj; 515 } 516 } 517 return null; 518 } 519 520 /** 521 * Returns the string in a given resource at the specified index. 522 * 523 * @param index an index to the wanted string. 524 * @return a string which lives in the resource. 525 * @throws IndexOutOfBoundsException If the index value is out of bounds of accepted values. 526 * @throws UResourceTypeMismatchException If resource bundle type mismatch. 527 */ getString(int index)528 public String getString(int index) { 529 ICUResourceBundle temp = (ICUResourceBundle)get(index); 530 if (temp.getType() == STRING) { 531 return temp.getString(); 532 } 533 throw new UResourceTypeMismatchException(""); 534 } 535 536 /** 537 * <strong>[icu]</strong> Returns the resource in a given resource at the specified index. 538 * 539 * @param index an index to the wanted resource. 540 * @return the sub resource UResourceBundle object 541 * @throws IndexOutOfBoundsException If the index value is out of bounds of accepted values. 542 * @throws MissingResourceException If the resource bundle is missing. 543 */ get(int index)544 public UResourceBundle get(int index) { 545 UResourceBundle obj = handleGet(index, null, this); 546 if (obj == null) { 547 obj = getParent(); 548 if (obj != null) { 549 obj = obj.get(index); 550 } 551 if (obj == null) 552 throw new MissingResourceException( 553 "Can't find resource for bundle " 554 + this.getClass().getName() + ", key " 555 + getKey(), this.getClass().getName(), getKey()); 556 } 557 return obj; 558 } 559 560 /** 561 * Returns a resource in a given resource that has a given index, or null if the 562 * resource is not found. 563 * 564 * @param index the index of the resource 565 * @return the resource, or null 566 * @see #get(int) 567 * @deprecated This API is ICU internal only. 568 * @hide draft / provisional / internal are hidden on OHOS 569 */ 570 @Deprecated findTopLevel(int index)571 protected UResourceBundle findTopLevel(int index) { 572 // NOTE: this _barely_ works for top-level resources. For resources at lower 573 // levels, it fails when you fall back to the parent, since you're now 574 // looking at root resources, not at the corresponding nested resource. 575 // Not only that, but unless the indices correspond 1-to-1, the index will 576 // lose meaning. Essentially this only works if the child resource arrays 577 // are prefixes of their parent arrays. 578 for (UResourceBundle res = this; res != null; res = res.getParent()) { 579 UResourceBundle obj = res.handleGet(index, null, this); 580 if (obj != null) { 581 return obj; 582 } 583 } 584 return null; 585 } 586 587 /** 588 * Returns the keys in this bundle as an enumeration 589 * @return an enumeration containing key strings, 590 * which is empty if this is not a bundle or a table resource 591 */ 592 @Override getKeys()593 public Enumeration<String> getKeys() { 594 return Collections.enumeration(keySet()); 595 } 596 597 /** 598 * Returns a Set of all keys contained in this ResourceBundle and its parent bundles. 599 * @return a Set of all keys contained in this ResourceBundle and its parent bundles, 600 * which is empty if this is not a bundle or a table resource 601 * @deprecated This API is ICU internal only. 602 * @hide draft / provisional / internal are hidden on OHOS 603 */ 604 @Override 605 @Deprecated keySet()606 public Set<String> keySet() { 607 // TODO: Java 6 ResourceBundle has keySet() which calls handleKeySet() 608 // and caches the results. 609 // When we upgrade to Java 6, we still need to check for isTopLevelResource(). 610 // Keep the else branch as is. The if body should just return super.keySet(). 611 // Remove then-redundant caching of the keys. 612 Set<String> keys = null; 613 ICUResourceBundle icurb = null; 614 if(isTopLevelResource() && this instanceof ICUResourceBundle) { 615 // We do not cache the top-level keys in this base class so that 616 // not every string/int/binary... resource has to have a keys cache field. 617 icurb = (ICUResourceBundle)this; 618 keys = icurb.getTopLevelKeySet(); 619 } 620 if(keys == null) { 621 if(isTopLevelResource()) { 622 TreeSet<String> newKeySet; 623 if(parent == null) { 624 newKeySet = new TreeSet<String>(); 625 } else if(parent instanceof UResourceBundle) { 626 newKeySet = new TreeSet<String>(((UResourceBundle)parent).keySet()); 627 } else { 628 // TODO: Java 6 ResourceBundle has keySet(); use it when we upgrade to Java 6 629 // and remove this else branch. 630 newKeySet = new TreeSet<String>(); 631 Enumeration<String> parentKeys = parent.getKeys(); 632 while(parentKeys.hasMoreElements()) { 633 newKeySet.add(parentKeys.nextElement()); 634 } 635 } 636 newKeySet.addAll(handleKeySet()); 637 keys = Collections.unmodifiableSet(newKeySet); 638 if(icurb != null) { 639 icurb.setTopLevelKeySet(keys); 640 } 641 } else { 642 return handleKeySet(); 643 } 644 } 645 return keys; 646 } 647 648 /** 649 * Returns a Set of the keys contained <i>only</i> in this ResourceBundle. 650 * This does not include further keys from parent bundles. 651 * @return a Set of the keys contained only in this ResourceBundle, 652 * which is empty if this is not a bundle or a table resource 653 * @deprecated This API is ICU internal only. 654 * @hide draft / provisional / internal are hidden on OHOS 655 */ 656 @Override 657 @Deprecated handleKeySet()658 protected Set<String> handleKeySet() { 659 return Collections.emptySet(); 660 } 661 662 /** 663 * <strong>[icu]</strong> Returns the size of a resource. Size for scalar types is always 1, and for 664 * vector/table types is the number of child resources. 665 * 666 * <br><b>Note:</b> Integer array is treated as a scalar type. There are no APIs to 667 * access individual members of an integer array. It is always returned as a whole. 668 * @return number of resources in a given resource. 669 */ getSize()670 public int getSize() { 671 return 1; 672 } 673 674 /** 675 * <strong>[icu]</strong> Returns the type of a resource. 676 * Available types are {@link #INT INT}, {@link #ARRAY ARRAY}, 677 * {@link #BINARY BINARY}, {@link #INT_VECTOR INT_VECTOR}, 678 * {@link #STRING STRING}, {@link #TABLE TABLE}. 679 * 680 * @return type of the given resource. 681 */ getType()682 public int getType() { 683 return NONE; 684 } 685 686 /** 687 * <strong>[icu]</strong> Return the version number associated with this UResourceBundle as an 688 * VersionInfo object. 689 * @return VersionInfo object containing the version of the bundle 690 */ getVersion()691 public VersionInfo getVersion() { 692 return null; 693 } 694 695 /** 696 * <strong>[icu]</strong> Returns the iterator which iterates over this 697 * resource bundle 698 * @return UResourceBundleIterator that iterates over the resources in the bundle 699 */ getIterator()700 public UResourceBundleIterator getIterator() { 701 return new UResourceBundleIterator(this); 702 } 703 704 /** 705 * <strong>[icu]</strong> Returns the key associated with a given resource. Not all the resources have 706 * a key - only those that are members of a table. 707 * @return a key associated to this resource, or null if it doesn't have a key 708 */ getKey()709 public String getKey() { 710 return null; 711 } 712 713 /** 714 * <strong>[icu]</strong> Resource type constant for "no resource". 715 */ 716 public static final int NONE = -1; 717 718 /** 719 * <strong>[icu]</strong> Resource type constant for strings. 720 */ 721 public static final int STRING = 0; 722 723 /** 724 * <strong>[icu]</strong> Resource type constant for binary data. 725 */ 726 public static final int BINARY = 1; 727 728 /** 729 * <strong>[icu]</strong> Resource type constant for tables of key-value pairs. 730 */ 731 public static final int TABLE = 2; 732 733 /** 734 * <strong>[icu]</strong> Resource type constant for a single 28-bit integer, interpreted as 735 * signed or unsigned by the getInt() function. 736 * @see #getInt 737 */ 738 public static final int INT = 7; 739 740 /** 741 * <strong>[icu]</strong> Resource type constant for arrays of resources. 742 */ 743 public static final int ARRAY = 8; 744 745 /** 746 * Resource type constant for vectors of 32-bit integers. 747 * @see #getIntVector 748 */ 749 public static final int INT_VECTOR = 14; 750 751 //====== protected members ============== 752 753 /** 754 * <strong>[icu]</strong> Actual worker method for fetching a resource based on the given key. 755 * Sub classes must override this method if they support resources with keys. 756 * @param aKey the key string of the resource to be fetched 757 * @param aliasesVisited hashtable object to hold references of resources already seen 758 * @param requested the original resource bundle object on which the get method was invoked. 759 * The requested bundle and the bundle on which this method is invoked 760 * are the same, except in the cases where aliases are involved. 761 * @return UResourceBundle a resource associated with the key 762 */ handleGet(String aKey, HashMap<String, String> aliasesVisited, UResourceBundle requested)763 protected UResourceBundle handleGet(String aKey, HashMap<String, String> aliasesVisited, 764 UResourceBundle requested) { 765 return null; 766 } 767 768 /** 769 * <strong>[icu]</strong> Actual worker method for fetching a resource based on the given index. 770 * Sub classes must override this method if they support arrays of resources. 771 * @param index the index of the resource to be fetched 772 * @param aliasesVisited hashtable object to hold references of resources already seen 773 * @param requested the original resource bundle object on which the get method was invoked. 774 * The requested bundle and the bundle on which this method is invoked 775 * are the same, except in the cases where aliases are involved. 776 * @return UResourceBundle a resource associated with the index 777 */ handleGet(int index, HashMap<String, String> aliasesVisited, UResourceBundle requested)778 protected UResourceBundle handleGet(int index, HashMap<String, String> aliasesVisited, 779 UResourceBundle requested) { 780 return null; 781 } 782 783 /** 784 * <strong>[icu]</strong> Actual worker method for fetching the array of strings in a resource. 785 * Sub classes must override this method if they support arrays of strings. 786 * @return String[] An array of strings containing strings 787 */ handleGetStringArray()788 protected String[] handleGetStringArray() { 789 return null; 790 } 791 792 /** 793 * <strong>[icu]</strong> Actual worker method for fetching the keys of resources contained in the resource. 794 * Sub classes must override this method if they support keys and associated resources. 795 * 796 * @return Enumeration An enumeration of all the keys in this resource. 797 */ handleGetKeys()798 protected Enumeration<String> handleGetKeys(){ 799 return null; 800 } 801 802 /** 803 * {@inheritDoc} 804 */ 805 // this method is declared in ResourceBundle class 806 // so cannot change the signature 807 // Override this method 808 @Override handleGetObject(String aKey)809 protected Object handleGetObject(String aKey) { 810 return handleGetObjectImpl(aKey, this); 811 } 812 813 /** 814 * Override the superclass method 815 */ 816 // To facilitate XPath style aliases we need a way to pass the reference 817 // to requested locale. The only way I could figure out is to implement 818 // the look up logic here. This has a disadvantage that if the client 819 // loads an ICUResourceBundle, calls ResourceBundle.getObject method 820 // with a key that does not exist in the bundle then the lookup is 821 // done twice before throwing a MissingResourceExpection. handleGetObjectImpl(String aKey, UResourceBundle requested)822 private Object handleGetObjectImpl(String aKey, UResourceBundle requested) { 823 Object obj = resolveObject(aKey, requested); 824 if (obj == null) { 825 UResourceBundle parentBundle = getParent(); 826 if (parentBundle != null) { 827 obj = parentBundle.handleGetObjectImpl(aKey, requested); 828 } 829 if (obj == null) 830 throw new MissingResourceException( 831 "Can't find resource for bundle " 832 + this.getClass().getName() + ", key " + aKey, 833 this.getClass().getName(), aKey); 834 } 835 return obj; 836 } 837 838 // Routine for figuring out the type of object to be returned 839 // string or string array resolveObject(String aKey, UResourceBundle requested)840 private Object resolveObject(String aKey, UResourceBundle requested) { 841 if (getType() == STRING) { 842 return getString(); 843 } 844 UResourceBundle obj = handleGet(aKey, null, requested); 845 if (obj != null) { 846 if (obj.getType() == STRING) { 847 return obj.getString(); 848 } 849 try { 850 if (obj.getType() == ARRAY) { 851 return obj.handleGetStringArray(); 852 } 853 } catch (UResourceTypeMismatchException ex) { 854 return obj; 855 } 856 } 857 return obj; 858 } 859 860 /** 861 * Is this a top-level resource, that is, a whole bundle? 862 * @return true if this is a top-level resource 863 * @deprecated This API is ICU internal only. 864 * @hide draft / provisional / internal are hidden on OHOS 865 */ 866 @Deprecated isTopLevelResource()867 protected boolean isTopLevelResource() { 868 return true; 869 } 870 } 871