65 |
baseName_<i>def. language</i> |
baseName_<i>def. language</i> |
66 |
baseName</pre> |
baseName</pre> |
67 |
* |
* |
68 |
* <p>A bundle is backed up by less specific bundles (omiting variant, country |
* <p>A bundle is backed up by less specific bundles (omitting variant, country |
69 |
* or language). But it is not backed up by the default language locale. |
* or language). But it is not backed up by the default language locale. |
70 |
* |
* |
71 |
* <p>If you provide a bundle for a given locale, say |
* <p>If you provide a bundle for a given locale, say |
239 |
*/ |
*/ |
240 |
protected void setParent(ResourceBundle parent) |
protected void setParent(ResourceBundle parent) |
241 |
{ |
{ |
|
// Shall we ignore the old parent? |
|
242 |
this.parent = parent; |
this.parent = parent; |
243 |
} |
} |
244 |
|
|
361 |
cache = new HashMap(); |
cache = new HashMap(); |
362 |
resourceBundleCache.put(classLoader, cache); |
resourceBundleCache.put(classLoader, cache); |
363 |
} |
} |
364 |
else |
else if (cache.containsKey(name)) |
365 |
{ |
{ |
366 |
Reference ref = (Reference) cache.get(name); |
Reference ref = (Reference) cache.get(name); |
367 |
if (ref != null) |
ResourceBundle result = null; |
368 |
{ |
// If REF is null, that means that we added a `null' value to |
369 |
ResourceBundle rb = (ResourceBundle) ref.get(); |
// the hash map. That means we failed to find the bundle |
370 |
if (rb != null) |
// previously, and we cached that fact. The JDK does this, so |
371 |
// rb should already have the right parent, except if |
// it must be ok. |
372 |
// something very strange happened. |
if (ref == null) |
373 |
return rb; |
throw new MissingResourceException("Bundle " + baseName |
374 |
} |
+ " not found", |
375 |
|
baseName, ""); |
376 |
|
else |
377 |
|
{ |
378 |
|
ResourceBundle rb = (ResourceBundle) ref.get(); |
379 |
|
if (rb != null) |
380 |
|
{ |
381 |
|
// RB should already have the right parent, except if |
382 |
|
// something very strange happened. |
383 |
|
return rb; |
384 |
|
} |
385 |
|
// If RB is null, then we previously found it but it was |
386 |
|
// collected. So we try again. |
387 |
|
} |
388 |
} |
} |
389 |
|
|
390 |
|
// It is ok if this returns null. We aren't required to have the |
391 |
|
// base bundle. |
392 |
ResourceBundle baseBundle = tryBundle(baseName, emptyLocale, |
ResourceBundle baseBundle = tryBundle(baseName, emptyLocale, |
393 |
classLoader, null, cache); |
classLoader, null, cache); |
|
if (baseBundle == null) |
|
|
// JDK says, that if one provides a bundle base_en_UK, one |
|
|
// must also provide the bundles base_en and base. |
|
|
// This implies that if there is no bundle for base, there |
|
|
// is no bundle at all. |
|
|
throw new MissingResourceException("Bundle " + baseName + " not found", |
|
|
baseName, ""); |
|
394 |
|
|
395 |
// Now use the default locale. |
// Now use our locale, followed by the default locale. We only |
396 |
|
// need to try the default locale if our locale is different, and |
397 |
|
// if our locale failed to yield a result other than the base |
398 |
|
// bundle. |
399 |
ResourceBundle bundle = tryLocalBundle(baseName, locale, |
ResourceBundle bundle = tryLocalBundle(baseName, locale, |
400 |
classLoader, baseBundle, cache); |
classLoader, baseBundle, cache); |
401 |
if (bundle == baseBundle && !locale.equals(Locale.getDefault())) |
if (bundle == baseBundle && !locale.equals(Locale.getDefault())) |
402 |
bundle = tryLocalBundle(baseName, Locale.getDefault(), |
{ |
403 |
classLoader, baseBundle, cache); |
bundle = tryLocalBundle(baseName, Locale.getDefault(), |
404 |
|
classLoader, baseBundle, cache); |
405 |
|
// We need to record that the argument locale maps to the |
406 |
|
// bundle we just found. If we didn't find a bundle, record |
407 |
|
// that instead. |
408 |
|
if (bundle == null) |
409 |
|
cache.put(name, null); |
410 |
|
else |
411 |
|
cache.put(name, new SoftReference(bundle)); |
412 |
|
} |
413 |
|
|
414 |
// Check whether baseName_locale has been loaded; if not, map the |
if (bundle == null) |
415 |
// "baseName" bundle to "baseName_locale" to avoid retrying to load |
throw new MissingResourceException("Bundle " + baseName + " not found", |
416 |
// baseName_locale. |
baseName, ""); |
|
Reference ref = (Reference) cache.get(name); |
|
|
if (ref == null) |
|
|
cache.put(name, new SoftReference(bundle)); |
|
417 |
|
|
418 |
return bundle; |
return bundle; |
419 |
} |
} |
456 |
HashMap cache) |
HashMap cache) |
457 |
{ |
{ |
458 |
// First look into the cache. |
// First look into the cache. |
459 |
// XXX We should remove cleared references from the cache. |
if (cache.containsKey(localizedName)) |
460 |
Reference ref = (Reference) cache.get(localizedName); |
{ |
461 |
if (ref != null) |
Reference ref = (Reference) cache.get(localizedName); |
462 |
{ |
ResourceBundle result = null; |
463 |
ResourceBundle rb = (ResourceBundle) ref.get(); |
// If REF is null, that means that we added a `null' value to |
464 |
if (rb != null) |
// the hash map. That means we failed to find the bundle |
465 |
// rb should already have the right parent, except if |
// previously, and we cached that fact. The JDK does this, so |
466 |
// something very strange happened. |
// it must be ok. |
467 |
return rb; |
if (ref == null) |
468 |
|
return null; |
469 |
|
else |
470 |
|
{ |
471 |
|
ResourceBundle rb = (ResourceBundle) ref.get(); |
472 |
|
if (rb != null) |
473 |
|
{ |
474 |
|
// RB should already have the right parent, except if |
475 |
|
// something very strange happened. |
476 |
|
return rb; |
477 |
|
} |
478 |
|
// If RB is null, then we previously found it but it was |
479 |
|
// collected. So we try again. |
480 |
|
} |
481 |
} |
} |
482 |
|
|
483 |
// foundBundle holds exact matches for the localizedName resource |
// foundBundle holds exact matches for the localizedName resource |
499 |
// ignore them all |
// ignore them all |
500 |
} |
} |
501 |
if (foundBundle == null) |
if (foundBundle == null) |
502 |
try |
{ |
503 |
{ |
try |
504 |
InputStream is; |
{ |
505 |
final String resourceName |
InputStream is; |
506 |
= localizedName.replace('.', '/') + ".properties"; |
final String resourceName |
507 |
if (classloader == null) |
= localizedName.replace('.', '/') + ".properties"; |
508 |
is = ClassLoader.getSystemResourceAsStream(resourceName); |
if (classloader == null) |
509 |
else |
is = ClassLoader.getSystemResourceAsStream(resourceName); |
510 |
is = classloader.getResourceAsStream(resourceName); |
else |
511 |
if (is != null) |
is = classloader.getResourceAsStream(resourceName); |
512 |
{ |
if (is != null) |
513 |
foundBundle = new PropertyResourceBundle(is); |
{ |
514 |
foundBundle.parent = bundle; |
foundBundle = new PropertyResourceBundle(is); |
515 |
foundBundle.locale = locale; |
foundBundle.parent = bundle; |
516 |
} |
foundBundle.locale = locale; |
517 |
} |
} |
518 |
catch (IOException ex) |
} |
519 |
{ |
catch (IOException ex) |
520 |
} |
{ |
521 |
|
} |
522 |
|
} |
523 |
|
|
524 |
if (foundBundle != null) |
// Put the result into the hash table. If we didn't find anything |
525 |
|
// here, we record our parent bundle. If we record `null' that means |
526 |
|
// nothing, not even the base, was found. |
527 |
|
if (foundBundle == null) |
528 |
|
foundBundle = bundle; |
529 |
|
if (foundBundle == null) |
530 |
|
cache.put(localizedName, null); |
531 |
|
else |
532 |
cache.put(localizedName, new SoftReference(foundBundle)); |
cache.put(localizedName, new SoftReference(foundBundle)); |
533 |
|
return foundBundle; |
|
return foundBundle != null ? foundBundle : bundle; |
|
534 |
} |
} |
535 |
|
|
536 |
/** |
/** |
538 |
* locales with the same language. |
* locales with the same language. |
539 |
* |
* |
540 |
* @param name the name |
* @param name the name |
541 |
* @param locale the locale, that must be used exactly |
* @param locale the locale |
542 |
* @param classloader the classloader |
* @param classloader the classloader |
543 |
* @param bundle the backup (parent) bundle |
* @param bundle the backup (parent) bundle |
544 |
* @return the resource bundle if it was loaded, otherwise the backup |
* @return the resource bundle if it was loaded, otherwise the backup |
545 |
*/ |
*/ |
546 |
private static final ResourceBundle tryLocalBundle(String baseName, |
private static final ResourceBundle tryLocalBundle(String baseName, |
547 |
Locale locale, |
Locale locale, |
548 |
ClassLoader classloader, |
ClassLoader classloader, |
549 |
ResourceBundle bundle, |
ResourceBundle bundle, |
550 |
HashMap cache) |
HashMap cache) |
551 |
{ |
{ |
552 |
final String language = locale.getLanguage(); |
final String language = locale.getLanguage(); |
553 |
|
final String country = locale.getCountry(); |
554 |
|
final String variant = locale.getVariant(); |
555 |
|
|
556 |
StringBuffer sb = new StringBuffer(60); |
StringBuffer sb = new StringBuffer(60); |
557 |
|
sb.append(baseName); |
558 |
|
sb.append('_'); |
559 |
|
|
560 |
if (language.length() > 0) |
if (language.length() > 0) |
561 |
{ |
{ |
562 |
final String country = locale.getCountry(); |
sb.append(language); |
563 |
sb.append(baseName).append('_').append(language); |
bundle = tryBundle(sb.toString(), new Locale(language), |
564 |
String name = sb.toString(); |
classloader, bundle, cache); |
|
|
|
|
if (country.length() != 0) |
|
|
{ |
|
|
bundle = tryBundle(name, new Locale(language), |
|
|
classloader, bundle, cache); |
|
|
sb.append('_').append(country); |
|
|
name = sb.toString(); |
|
|
|
|
|
final String variant = locale.getVariant(); |
|
|
|
|
|
if (variant.length() != 0) |
|
|
{ |
|
|
bundle = tryBundle(name, new Locale(language, country), |
|
|
classloader, bundle, cache); |
|
|
sb.append('_').append(variant); |
|
|
name = sb.toString(); |
|
|
} |
|
|
} |
|
|
bundle = tryBundle(name, locale, classloader, bundle, cache); |
|
565 |
} |
} |
566 |
|
// If LANGUAGE was empty, we still need to try the other |
567 |
|
// components, and the `_' is required. |
568 |
|
sb.append('_'); |
569 |
|
|
570 |
|
if (country.length() > 0) |
571 |
|
{ |
572 |
|
sb.append(country); |
573 |
|
bundle = tryBundle(sb.toString(), new Locale(language, country), |
574 |
|
classloader, bundle, cache); |
575 |
|
} |
576 |
|
sb.append('_'); |
577 |
|
|
578 |
|
if (variant.length() > 0) |
579 |
|
{ |
580 |
|
sb.append(variant); |
581 |
|
bundle = tryBundle(sb.toString(), locale, |
582 |
|
classloader, bundle, cache); |
583 |
|
} |
584 |
|
|
585 |
return bundle; |
return bundle; |
586 |
} |
} |
587 |
} // class ResourceBundle |
} |