equal
deleted
inserted
replaced
55 import java.util.concurrent.ConcurrentHashMap; |
55 import java.util.concurrent.ConcurrentHashMap; |
56 import java.util.concurrent.ConcurrentMap; |
56 import java.util.concurrent.ConcurrentMap; |
57 import java.util.jar.JarEntry; |
57 import java.util.jar.JarEntry; |
58 import java.util.spi.ResourceBundleControlProvider; |
58 import java.util.spi.ResourceBundleControlProvider; |
59 |
59 |
|
60 import sun.reflect.CallerSensitive; |
|
61 import sun.reflect.Reflection; |
60 import sun.util.locale.BaseLocale; |
62 import sun.util.locale.BaseLocale; |
61 import sun.util.locale.LocaleObjectCache; |
63 import sun.util.locale.LocaleObjectCache; |
62 |
64 |
63 |
65 |
64 /** |
66 /** |
438 return locale; |
440 return locale; |
439 } |
441 } |
440 |
442 |
441 /* |
443 /* |
442 * Automatic determination of the ClassLoader to be used to load |
444 * Automatic determination of the ClassLoader to be used to load |
443 * resources on behalf of the client. N.B. The client is getLoader's |
445 * resources on behalf of the client. |
444 * caller's caller. |
446 */ |
445 */ |
447 private static ClassLoader getLoader(Class<?> caller) { |
446 private static ClassLoader getLoader() { |
448 ClassLoader cl = caller == null ? null : caller.getClassLoader(); |
447 Class<?>[] stack = getClassContext(); |
|
448 /* Magic number 2 identifies our caller's caller */ |
|
449 Class<?> c = stack[2]; |
|
450 ClassLoader cl = (c == null) ? null : c.getClassLoader(); |
|
451 if (cl == null) { |
449 if (cl == null) { |
452 // When the caller's loader is the boot class loader, cl is null |
450 // When the caller's loader is the boot class loader, cl is null |
453 // here. In that case, ClassLoader.getSystemClassLoader() may |
451 // here. In that case, ClassLoader.getSystemClassLoader() may |
454 // return the same class loader that the application is |
452 // return the same class loader that the application is |
455 // using. We therefore use a wrapper ClassLoader to create a |
453 // using. We therefore use a wrapper ClassLoader to create a |
459 cl = RBClassLoader.INSTANCE; |
457 cl = RBClassLoader.INSTANCE; |
460 } |
458 } |
461 return cl; |
459 return cl; |
462 } |
460 } |
463 |
461 |
464 private static native Class<?>[] getClassContext(); |
|
465 |
|
466 /** |
462 /** |
467 * A wrapper of ClassLoader.getSystemClassLoader(). |
463 * A wrapper of ClassLoader.getSystemClassLoader(). |
468 */ |
464 */ |
469 private static class RBClassLoader extends ClassLoader { |
465 private static class RBClassLoader extends ClassLoader { |
470 private static final RBClassLoader INSTANCE = AccessController.doPrivileged( |
466 private static final RBClassLoader INSTANCE = AccessController.doPrivileged( |
744 * if <code>baseName</code> is <code>null</code> |
740 * if <code>baseName</code> is <code>null</code> |
745 * @exception MissingResourceException |
741 * @exception MissingResourceException |
746 * if no resource bundle for the specified base name can be found |
742 * if no resource bundle for the specified base name can be found |
747 * @return a resource bundle for the given base name and the default locale |
743 * @return a resource bundle for the given base name and the default locale |
748 */ |
744 */ |
|
745 @CallerSensitive |
749 public static final ResourceBundle getBundle(String baseName) |
746 public static final ResourceBundle getBundle(String baseName) |
750 { |
747 { |
751 return getBundleImpl(baseName, Locale.getDefault(), |
748 return getBundleImpl(baseName, Locale.getDefault(), |
752 /* must determine loader here, else we break stack invariant */ |
749 getLoader(Reflection.getCallerClass()), |
753 getLoader(), |
|
754 getDefaultControl(baseName)); |
750 getDefaultControl(baseName)); |
755 } |
751 } |
756 |
752 |
757 /** |
753 /** |
758 * Returns a resource bundle using the specified base name, the |
754 * Returns a resource bundle using the specified base name, the |
786 * (e.g., <code>control.getCandidateLocales</code> returns null.) |
782 * (e.g., <code>control.getCandidateLocales</code> returns null.) |
787 * Note that validation of <code>control</code> is performed as |
783 * Note that validation of <code>control</code> is performed as |
788 * needed. |
784 * needed. |
789 * @since 1.6 |
785 * @since 1.6 |
790 */ |
786 */ |
|
787 @CallerSensitive |
791 public static final ResourceBundle getBundle(String baseName, |
788 public static final ResourceBundle getBundle(String baseName, |
792 Control control) { |
789 Control control) { |
793 return getBundleImpl(baseName, Locale.getDefault(), |
790 return getBundleImpl(baseName, Locale.getDefault(), |
794 /* must determine loader here, else we break stack invariant */ |
791 getLoader(Reflection.getCallerClass()), |
795 getLoader(), |
|
796 control); |
792 control); |
797 } |
793 } |
798 |
794 |
799 /** |
795 /** |
800 * Gets a resource bundle using the specified base name and locale, |
796 * Gets a resource bundle using the specified base name and locale, |
815 * if <code>baseName</code> or <code>locale</code> is <code>null</code> |
811 * if <code>baseName</code> or <code>locale</code> is <code>null</code> |
816 * @exception MissingResourceException |
812 * @exception MissingResourceException |
817 * if no resource bundle for the specified base name can be found |
813 * if no resource bundle for the specified base name can be found |
818 * @return a resource bundle for the given base name and locale |
814 * @return a resource bundle for the given base name and locale |
819 */ |
815 */ |
|
816 @CallerSensitive |
820 public static final ResourceBundle getBundle(String baseName, |
817 public static final ResourceBundle getBundle(String baseName, |
821 Locale locale) |
818 Locale locale) |
822 { |
819 { |
823 return getBundleImpl(baseName, locale, |
820 return getBundleImpl(baseName, locale, |
824 /* must determine loader here, else we break stack invariant */ |
821 getLoader(Reflection.getCallerClass()), |
825 getLoader(), |
|
826 getDefaultControl(baseName)); |
822 getDefaultControl(baseName)); |
827 } |
823 } |
828 |
824 |
829 /** |
825 /** |
830 * Returns a resource bundle using the specified base name, target |
826 * Returns a resource bundle using the specified base name, target |
861 * (e.g., <code>control.getCandidateLocales</code> returns null.) |
857 * (e.g., <code>control.getCandidateLocales</code> returns null.) |
862 * Note that validation of <code>control</code> is performed as |
858 * Note that validation of <code>control</code> is performed as |
863 * needed. |
859 * needed. |
864 * @since 1.6 |
860 * @since 1.6 |
865 */ |
861 */ |
|
862 @CallerSensitive |
866 public static final ResourceBundle getBundle(String baseName, Locale targetLocale, |
863 public static final ResourceBundle getBundle(String baseName, Locale targetLocale, |
867 Control control) { |
864 Control control) { |
868 return getBundleImpl(baseName, targetLocale, |
865 return getBundleImpl(baseName, targetLocale, |
869 /* must determine loader here, else we break stack invariant */ |
866 getLoader(Reflection.getCallerClass()), |
870 getLoader(), |
|
871 control); |
867 control); |
872 } |
868 } |
873 |
869 |
874 /** |
870 /** |
875 * Gets a resource bundle using the specified base name, locale, and class |
871 * Gets a resource bundle using the specified base name, locale, and class |
1719 * using the caller's class loader. |
1715 * using the caller's class loader. |
1720 * |
1716 * |
1721 * @since 1.6 |
1717 * @since 1.6 |
1722 * @see ResourceBundle.Control#getTimeToLive(String,Locale) |
1718 * @see ResourceBundle.Control#getTimeToLive(String,Locale) |
1723 */ |
1719 */ |
|
1720 @CallerSensitive |
1724 public static final void clearCache() { |
1721 public static final void clearCache() { |
1725 clearCache(getLoader()); |
1722 clearCache(getLoader(Reflection.getCallerClass())); |
1726 } |
1723 } |
1727 |
1724 |
1728 /** |
1725 /** |
1729 * Removes all resource bundles from the cache that have been loaded |
1726 * Removes all resource bundles from the cache that have been loaded |
1730 * using the given class loader. |
1727 * using the given class loader. |