214 * will locate resource bundles in the caller's module (<em>caller module</em>).</li> |
214 * will locate resource bundles in the caller's module (<em>caller module</em>).</li> |
215 * <li>If resource bundles are deployed in named modules separate from |
215 * <li>If resource bundles are deployed in named modules separate from |
216 * the caller module, those resource bundles need to be loaded from service |
216 * the caller module, those resource bundles need to be loaded from service |
217 * providers of {@link ResourceBundleProvider}. The caller module must declare |
217 * providers of {@link ResourceBundleProvider}. The caller module must declare |
218 * "{@code uses}" and the service interface name is the concatenation of the |
218 * "{@code uses}" and the service interface name is the concatenation of the |
219 * base name of the bundles and the string "{@code Provider}". The |
219 * package name of the base name, string "{@code .spi.}", the simple class |
|
220 * name of the base name, and the string "{@code Provider}". The |
220 * <em>bundle provider modules</em> containing resource bundles must |
221 * <em>bundle provider modules</em> containing resource bundles must |
221 * declare "{@code provides}" with the service interface name and |
222 * declare "{@code provides}" with the service interface name and |
222 * its implementation class name. For example, if the base name is |
223 * its implementation class name. For example, if the base name is |
223 * "{@code com.example.app.MyResources}", the caller module must declare |
224 * "{@code com.example.app.MyResources}", the caller module must declare |
224 * "{@code uses com.example.app.MyResourcesProvider;}" and a module containing resource |
225 * "{@code uses com.example.app.spi.MyResourcesProvider;}" and a module containing resource |
225 * bundles must declare "{@code provides com.example.app.MyResourcesProvider |
226 * bundles must declare "{@code provides com.example.app.spi.MyResourcesProvider |
226 * with com.example.app.internal.MyResourcesProviderImpl;}" |
227 * with com.example.app.internal.MyResourcesProviderImpl;}" |
227 * where {@code com.example.app.internal.MyResourcesProviderImpl} is an |
228 * where {@code com.example.app.internal.MyResourcesProviderImpl} is an |
228 * implementation class of {@code com.example.app.MyResourcesProvider}.</li> |
229 * implementation class of {@code com.example.app.spi.MyResourcesProvider}.</li> |
229 * <li>If you want to use non-standard formats in named modules, such as XML, |
230 * <li>If you want to use non-standard formats in named modules, such as XML, |
230 * {@link ResourceBundleProvider} needs to be used.</li> |
231 * {@link ResourceBundleProvider} needs to be used.</li> |
231 * <li>The {@code getBundle} method with a {@code ClassLoader} may not be able to |
232 * <li>The {@code getBundle} method with a {@code ClassLoader} may not be able to |
232 * find resource bundles using the given {@code ClassLoader} in named modules. |
233 * find resource bundles using the given {@code ClassLoader} in named modules. |
233 * The {@code getBundle} method with a {@code Module} can be used, instead.</li> |
234 * The {@code getBundle} method with a {@code Module} can be used, instead.</li> |
241 * |
242 * |
242 * <h3><a id="RBP_support">ResourceBundleProvider Service Providers</a></h3> |
243 * <h3><a id="RBP_support">ResourceBundleProvider Service Providers</a></h3> |
243 * |
244 * |
244 * The {@code getBundle} factory methods load service providers of |
245 * The {@code getBundle} factory methods load service providers of |
245 * {@link ResourceBundleProvider}, if available, using {@link ServiceLoader}. |
246 * {@link ResourceBundleProvider}, if available, using {@link ServiceLoader}. |
246 * The service type is designated by {@code basename+"Provider"}. For |
247 * The service type is designated by |
|
248 * {@code <package name> + ".spi." + <simple name> + "Provider"}. For |
247 * example, if the base name is "{@code com.example.app.MyResources}", the service |
249 * example, if the base name is "{@code com.example.app.MyResources}", the service |
248 * type is {@code com.example.app.MyResourcesProvider}. |
250 * type is {@code com.example.app.spi.MyResourcesProvider}. |
249 * <p> |
251 * <p> |
250 * In named modules, the loaded service providers for the given base name are |
252 * In named modules, the loaded service providers for the given base name are |
251 * used to load resource bundles. If no service provider is available, or if |
253 * used to load resource bundles. If no service provider is available, or if |
252 * none of the service providers returns a resource bundle and the caller module |
254 * none of the service providers returns a resource bundle and the caller module |
253 * doesn't have its own service provider, the {@code getBundle} factory method |
255 * doesn't have its own service provider, the {@code getBundle} factory method |
921 * </blockquote> |
923 * </blockquote> |
922 * |
924 * |
923 * <p> Resource bundles in named modules may be encapsulated. When |
925 * <p> Resource bundles in named modules may be encapsulated. When |
924 * the resource bundle is loaded from a provider, the caller module |
926 * the resource bundle is loaded from a provider, the caller module |
925 * must have an appropriate <i>uses</i> clause in its <i>module descriptor</i> |
927 * must have an appropriate <i>uses</i> clause in its <i>module descriptor</i> |
926 * to declare that the module uses implementations of {@code "baseName"Provider}. |
928 * to declare that the module uses implementations of |
|
929 * {@code <package name> + ".spi." + <simple name> + "Provider"}. |
|
930 * Otherwise, it will load the resource bundles that are local in the |
|
931 * given module or that are visible to the class loader of the given module |
|
932 * (refer to the <a href="#bundleprovider">Resource Bundles in Named Modules</a> |
|
933 * section for details). |
927 * When the resource bundle is loaded from the specified module, it is |
934 * When the resource bundle is loaded from the specified module, it is |
928 * subject to the encapsulation rules specified by |
935 * subject to the encapsulation rules specified by |
929 * {@link Module#getResourceAsStream Module.getResourceAsStream}. |
936 * {@link Module#getResourceAsStream Module.getResourceAsStream}. |
930 * |
937 * |
931 * @param baseName the base name of the resource bundle, |
938 * @param baseName the base name of the resource bundle, |
956 * on behalf of the specified module. |
963 * on behalf of the specified module. |
957 * |
964 * |
958 * <p> Resource bundles in named modules may be encapsulated. When |
965 * <p> Resource bundles in named modules may be encapsulated. When |
959 * the resource bundle is loaded from a provider, the caller module |
966 * the resource bundle is loaded from a provider, the caller module |
960 * must have an appropriate <i>uses</i> clause in its <i>module descriptor</i> |
967 * must have an appropriate <i>uses</i> clause in its <i>module descriptor</i> |
961 * to declare that the module uses implementations of {@code "baseName"Provider}. |
968 * to declare that the module uses implementations of |
|
969 * {@code <package name> + ".spi." + <simple name> + "Provider"}. |
|
970 * Otherwise, it will load the resource bundles that are local in the |
|
971 * given module or that are visible to the class loader of the given module |
|
972 * (refer to the <a href="#bundleprovider">Resource Bundles in Named Modules</a> |
|
973 * section for details). |
962 * When the resource bundle is loaded from the specified module, it is |
974 * When the resource bundle is loaded from the specified module, it is |
963 * subject to the encapsulation rules specified by |
975 * subject to the encapsulation rules specified by |
964 * {@link Module#getResourceAsStream Module.getResourceAsStream}. |
976 * {@link Module#getResourceAsStream Module.getResourceAsStream}. |
965 * |
|
966 * <p> |
|
967 * If the given {@code module} is a named module, this method will |
|
968 * load the service providers for {@link java.util.spi.ResourceBundleProvider} |
|
969 * and also resource bundles that are local in the given module or that |
|
970 * are visible to the class loader of the given module (refer to the |
|
971 * <a href="#bundleprovider">Resource Bundles in Named Modules</a> section |
|
972 * for details). |
|
973 * |
977 * |
974 * <p> |
978 * <p> |
975 * If the given {@code module} is an unnamed module, then this method is |
979 * If the given {@code module} is an unnamed module, then this method is |
976 * equivalent to calling {@link #getBundle(String, Locale, ClassLoader) |
980 * equivalent to calling {@link #getBundle(String, Locale, ClassLoader) |
977 * getBundle(baseName, targetLocale, module.getClassLoader()} to load |
981 * getBundle(baseName, targetLocale, module.getClassLoader()} to load |
1068 * |
1072 * |
1069 * <p> |
1073 * <p> |
1070 * Resource bundles in a named module are private to that module. If |
1074 * Resource bundles in a named module are private to that module. If |
1071 * the caller is in a named module, this method will find resource bundles |
1075 * the caller is in a named module, this method will find resource bundles |
1072 * from the service providers of {@link java.util.spi.ResourceBundleProvider} |
1076 * from the service providers of {@link java.util.spi.ResourceBundleProvider} |
1073 * and also find resource bundles that are in the caller's module or |
1077 * if any. Otherwise, it will load the resource bundles that are visible to |
1074 * that are visible to the given class loader. |
1078 * the given {@code loader} (refer to the |
|
1079 * <a href="#bundleprovider">Resource Bundles in Named Modules</a> section |
|
1080 * for details). |
1075 * If the caller is in a named module and the given {@code loader} is |
1081 * If the caller is in a named module and the given {@code loader} is |
1076 * different than the caller's class loader, or if the caller is not in |
1082 * different than the caller's class loader, or if the caller is not in |
1077 * a named module, this method will not find resource bundles from named |
1083 * a named module, this method will not find resource bundles from named |
1078 * modules. |
1084 * modules. |
1079 * |
1085 * |
1881 * to the given class loader |
1887 * to the given class loader |
1882 */ |
1888 */ |
1883 private static Class<ResourceBundleProvider> |
1889 private static Class<ResourceBundleProvider> |
1884 getResourceBundleProviderType(String baseName, ClassLoader loader) |
1890 getResourceBundleProviderType(String baseName, ClassLoader loader) |
1885 { |
1891 { |
1886 // Look up <baseName> + "Provider" |
1892 // Look up <packagename> + ".spi." + <name>"Provider" |
1887 String providerName = baseName + "Provider"; |
1893 int i = baseName.lastIndexOf('.'); |
|
1894 if (i <= 0) { |
|
1895 return null; |
|
1896 } |
|
1897 |
|
1898 String name = baseName.substring(i+1, baseName.length()) + "Provider"; |
|
1899 String providerName = baseName.substring(0, i) + ".spi." + name; |
|
1900 |
1888 // Use the class loader of the getBundle caller so that the caller's |
1901 // Use the class loader of the getBundle caller so that the caller's |
1889 // visibility of the provider type is checked. |
1902 // visibility of the provider type is checked. |
1890 return AccessController.doPrivileged( |
1903 return AccessController.doPrivileged( |
1891 new PrivilegedAction<>() { |
1904 new PrivilegedAction<>() { |
1892 @Override |
1905 @Override |