| 1 7 8 22 23 package java.util; 24 25 import java.io.InputStream ; 26 import java.lang.ref.Reference ; 27 import java.lang.ref.ReferenceQueue ; 28 import java.lang.ref.WeakReference ; 29 import sun.misc.SoftCache; 30 31 195 abstract public class ResourceBundle { 196 204 private static final ResourceCacheKey cacheKey = new ResourceCacheKey(); 205 206 207 private static final int INITIAL_CACHE_SIZE = 25; 208 209 210 private static final float CACHE_LOAD_FACTOR = (float)1.0; 211 212 216 private static final int MAX_BUNDLES_SEARCHED = 3; 217 218 227 private static final Hashtable underConstruction = new Hashtable (MAX_BUNDLES_SEARCHED, CACHE_LOAD_FACTOR); 228 229 230 private static final Object NOT_FOUND = new Object (); 231 232 245 private static SoftCache cacheList = new SoftCache(INITIAL_CACHE_SIZE, CACHE_LOAD_FACTOR); 246 247 250 private static ReferenceQueue referenceQueue = new ReferenceQueue (); 251 252 257 protected ResourceBundle parent = null; 258 259 262 private Locale locale = null; 263 264 268 public ResourceBundle() { 269 } 270 271 284 public final String getString(String key) { 285 return (String ) getObject(key); 286 } 287 288 301 public final String [] getStringArray(String key) { 302 return (String []) getObject(key); 303 } 304 305 318 public final Object getObject(String key) { 319 Object obj = handleGetObject(key); 320 if (obj == null) { 321 if (parent != null) { 322 obj = parent.getObject(key); 323 } 324 if (obj == null) 325 throw new MissingResourceException ("Can't find resource for bundle " 326 +this.getClass().getName() 327 +", key "+key, 328 this.getClass().getName(), 329 key); 330 } 331 return obj; 332 } 333 334 341 public Locale getLocale() { 342 return locale; 343 } 344 345 355 private void setLocale(String baseName, String bundleName) { 356 if (baseName.length() == bundleName.length()) { 357 locale = new Locale ("", ""); 358 } else if (baseName.length() < bundleName.length()) { 359 int pos = baseName.length(); 360 String temp = bundleName.substring(pos + 1); 361 pos = temp.indexOf('_'); 362 if (pos == -1) { 363 locale = new Locale (temp, "", ""); 364 return; 365 } 366 367 String language = temp.substring(0, pos); 368 temp = temp.substring(pos + 1); 369 pos = temp.indexOf('_'); 370 if (pos == -1) { 371 locale = new Locale (language, temp, ""); 372 return; 373 } 374 375 String country = temp.substring(0, pos); 376 temp = temp.substring(pos + 1); 377 378 locale = new Locale (language, country, temp); 379 } else { 380 throw new IllegalArgumentException (); 383 } 384 } 385 386 391 private static ClassLoader getLoader() { 392 Class [] stack = getClassContext(); 393 394 Class c = stack[2]; 395 ClassLoader cl = (c == null) ? null : c.getClassLoader(); 396 if (cl == null) { 397 cl = ClassLoader.getSystemClassLoader(); 398 } 399 return cl; 400 } 401 402 private static native Class [] getClassContext(); 403 404 411 protected void setParent( ResourceBundle parent ) { 412 this.parent = parent; 413 } 414 415 425 private static final class ResourceCacheKey implements Cloneable { 426 private LoaderReference loaderRef; 427 private String searchName; 428 private Locale defaultLocale; 429 private int hashCodeCache; 430 431 public boolean equals(Object other) { 432 if (this == other) { 433 return true; 434 } 435 try { 436 final ResourceCacheKey otherEntry = (ResourceCacheKey)other; 437 if (hashCodeCache != otherEntry.hashCodeCache) { 439 return false; 440 } 441 if (!searchName.equals(otherEntry.searchName)) { 443 return false; 444 } 445 if (defaultLocale == null) { 447 if (otherEntry.defaultLocale != null) { 448 return false; 449 } 450 } else { 451 if (!defaultLocale.equals(otherEntry.defaultLocale)) { 452 return false; 453 } 454 } 455 if (loaderRef == null) { 457 return otherEntry.loaderRef == null; 458 } else { 459 Object loaderRefValue = loaderRef.get(); 460 return (otherEntry.loaderRef != null) 461 && (loaderRefValue != null) 465 && (loaderRefValue == otherEntry.loaderRef.get()); 466 } 467 } catch (NullPointerException e) { 468 return false; 469 } catch (ClassCastException e) { 470 return false; 471 } 472 } 473 474 public int hashCode() { 475 return hashCodeCache; 476 } 477 478 public Object clone() { 479 try { 480 ResourceCacheKey clone = (ResourceCacheKey) super.clone(); 481 if (loaderRef != null) { 482 clone.loaderRef = new LoaderReference(loaderRef.get(), referenceQueue, clone); 483 } 484 return clone; 485 } catch (CloneNotSupportedException e) { 486 throw new InternalError (); 488 } 489 } 490 491 public void setKeyValues(ClassLoader loader, String searchName, Locale defaultLocale) { 492 this.searchName = searchName; 493 hashCodeCache = searchName.hashCode(); 494 this.defaultLocale = defaultLocale; 495 if (defaultLocale != null) { 496 hashCodeCache ^= defaultLocale.hashCode(); 497 } 498 if (loader == null) { 499 this.loaderRef = null; 500 } else { 501 loaderRef = new LoaderReference(loader, referenceQueue, this); 502 hashCodeCache ^= loader.hashCode(); 503 } 504 } 505 506 public void clear() { 507 setKeyValues(null, "", null); 508 } 509 } 510 511 516 private static final class LoaderReference extends WeakReference { 517 private ResourceCacheKey cacheKey; 518 519 LoaderReference(Object referent, ReferenceQueue q, ResourceCacheKey key) { 520 super(referent, q); 521 cacheKey = key; 522 } 523 524 ResourceCacheKey getCacheKey() { 525 return cacheKey; 526 } 527 } 528 529 547 public static final ResourceBundle getBundle(String baseName) 548 { 549 return getBundleImpl(baseName, Locale.getDefault(), 550 551 getLoader()); 552 } 553 554 573 public static final ResourceBundle getBundle(String baseName, 574 Locale locale) 575 { 576 return getBundleImpl(baseName, locale, getLoader()); 577 } 578 579 693 public static ResourceBundle getBundle(String baseName, Locale locale, 694 ClassLoader loader) 695 { 696 if (loader == null) { 697 throw new NullPointerException (); 698 } 699 return getBundleImpl(baseName, locale, loader); 700 } 701 702 private static ResourceBundle getBundleImpl(String baseName, Locale locale, 703 ClassLoader loader) 704 { 705 if (baseName == null) { 706 throw new NullPointerException (); 707 } 708 709 String bundleName = baseName; 711 String localeSuffix = locale.toString(); 712 if (localeSuffix.length() > 0) { 713 bundleName += "_" + localeSuffix; 714 } else if (locale.getVariant().length() > 0) { 715 bundleName += "___" + locale.getVariant(); 718 } 719 720 Locale defaultLocale = Locale.getDefault(); 723 724 Object lookup = findBundleInCache(loader, bundleName, defaultLocale); 725 if (lookup == NOT_FOUND) { 726 throwMissingResourceException(baseName, locale); 727 } else if (lookup != null) { 728 return (ResourceBundle )lookup; 729 } 730 731 735 740 Object parent = NOT_FOUND; 741 try { 742 Object root = findBundle(loader, baseName, defaultLocale, baseName, null); 744 if (root == null) { 745 putBundleInCache(loader, baseName, defaultLocale, NOT_FOUND); 746 root = NOT_FOUND; 747 } 748 749 final Vector names = calculateBundleNames(baseName, locale); 753 Vector bundlesFound = new Vector (MAX_BUNDLES_SEARCHED); 754 boolean foundInMainBranch = (root != NOT_FOUND && names.size() == 0); 757 758 if (!foundInMainBranch) { 759 parent = root; 760 for (int i = 0; i < names.size(); i++) { 761 bundleName = (String )names.elementAt(i); 762 lookup = findBundle(loader, bundleName, defaultLocale, baseName, parent); 763 bundlesFound.addElement(lookup); 764 if (lookup != null) { 765 parent = lookup; 766 foundInMainBranch = true; 767 } 768 } 769 } 770 parent = root; 771 if (!foundInMainBranch) { 772 final Vector fallbackNames = calculateBundleNames(baseName, defaultLocale); 774 for (int i = 0; i < fallbackNames.size(); i++) { 775 bundleName = (String )fallbackNames.elementAt(i); 776 if (names.contains(bundleName)) { 777 break; 779 } 780 lookup = findBundle(loader, bundleName, defaultLocale, baseName, parent); 781 if (lookup != null) { 782 parent = lookup; 783 } else { 784 putBundleInCache(loader, bundleName, defaultLocale, parent); 787 } 788 } 789 } 790 parent = propagate(loader, names, bundlesFound, defaultLocale, parent); 792 } catch (Exception e) { 793 cleanUpConstructionList(); 796 throwMissingResourceException(baseName, locale); 797 } catch (Error e) { 798 cleanUpConstructionList(); 802 throw e; 803 } 804 if (parent == NOT_FOUND) { 805 throwMissingResourceException(baseName, locale); 806 } 807 return (ResourceBundle )parent; 808 } 809 810 819 private static Object propagate(ClassLoader loader, Vector names, 820 Vector bundlesFound, Locale defaultLocale, Object parent) { 821 for (int i = 0; i < names.size(); i++) { 822 final String bundleName = (String )names.elementAt(i); 823 final Object lookup = bundlesFound.elementAt(i); 824 if (lookup == null) { 825 putBundleInCache(loader, bundleName, defaultLocale, parent); 826 } else { 827 parent = lookup; 828 } 829 } 830 return parent; 831 } 832 833 834 private static void throwMissingResourceException(String baseName, Locale locale) 835 throws MissingResourceException { 836 throw new MissingResourceException ("Can't find bundle for base name " 837 + baseName + ", locale " + locale, 838 baseName + "_" + locale,""); 839 } 840 841 846 private static void cleanUpConstructionList() { 847 synchronized (cacheList) { 848 final Collection entries = underConstruction.values(); 849 final Thread thisThread = Thread.currentThread(); 850 while (entries.remove(thisThread)) { 851 } 852 cacheList.notifyAll(); 855 } 856 } 857 858 |