use of java.util.spi.ResourceBundleProvider in project Bytecoder by mirkosertic.
the class Bundles method findBundleOf.
private static ResourceBundle findBundleOf(CacheKey cacheKey, Strategy strategy, String baseName, List<Locale> candidateLocales, int index) {
ResourceBundle parent = null;
Locale targetLocale = candidateLocales.get(index);
if (index != candidateLocales.size() - 1) {
parent = findBundleOf(cacheKey, strategy, baseName, candidateLocales, index + 1);
}
// Before we do the real loading work, see whether we need to
// do some housekeeping: If resource bundles have been nulled out,
// remove all related information from the cache.
cleanupCache();
// find an individual ResourceBundle in the cache
cacheKey.setLocale(targetLocale);
ResourceBundle bundle = findBundleInCache(cacheKey);
if (bundle != null) {
if (bundle == NONEXISTENT_BUNDLE) {
return parent;
}
if (bundleAccess.getParent(bundle) == parent) {
return bundle;
}
// Remove bundle from the cache.
BundleReference bundleRef = cacheList.get(cacheKey);
if (bundleRef != null && bundleRef.get() == bundle) {
cacheList.remove(cacheKey, bundleRef);
}
}
// Determine if providers should be used for loading the bundle.
// An assumption here is that if the leaf bundle of a look-up path is
// in java.base, all bundles of the path are in java.base.
// (e.g., en_US of path en_US -> en -> root is in java.base and the rest
// are in java.base as well)
// This assumption isn't valid for general bundle loading.
ServiceLoader<ResourceBundleProvider> providers = cacheKey.getProviders();
if (providers != null) {
if (strategy.getResourceBundleProviderType(baseName, targetLocale) == null) {
providers = null;
}
}
CacheKey constKey = (CacheKey) cacheKey.clone();
try {
if (providers != null) {
bundle = loadBundleFromProviders(baseName, targetLocale, providers, cacheKey);
} else {
try {
String bundleName = strategy.toBundleName(baseName, targetLocale);
Class<?> c = Class.forName(Bundles.class.getModule(), bundleName);
if (c != null && ResourceBundle.class.isAssignableFrom(c)) {
@SuppressWarnings("unchecked") Class<ResourceBundle> bundleClass = (Class<ResourceBundle>) c;
bundle = bundleAccess.newResourceBundle(bundleClass);
}
} catch (Exception e) {
cacheKey.setCause(e);
}
}
} finally {
if (constKey.getCause() instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
}
if (bundle == null) {
// Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
// instance for the locale.
putBundleInCache(cacheKey, NONEXISTENT_BUNDLE);
return parent;
}
if (parent != null && bundleAccess.getParent(bundle) == null) {
bundleAccess.setParent(bundle, parent);
}
bundleAccess.setLocale(bundle, targetLocale);
bundleAccess.setName(bundle, baseName);
bundle = putBundleInCache(cacheKey, bundle);
return bundle;
}
use of java.util.spi.ResourceBundleProvider in project Bytecoder by mirkosertic.
the class Bundles method loadBundleOf.
private static ResourceBundle loadBundleOf(String baseName, Locale targetLocale, Strategy strategy) {
Objects.requireNonNull(baseName);
Objects.requireNonNull(targetLocale);
Objects.requireNonNull(strategy);
CacheKey cacheKey = new CacheKey(baseName, targetLocale);
ResourceBundle bundle = null;
// Quick lookup of the cache.
BundleReference bundleRef = cacheList.get(cacheKey);
if (bundleRef != null) {
bundle = bundleRef.get();
}
// then return this bundle.
if (isValidBundle(bundle)) {
return bundle;
}
// Get the providers for loading the "leaf" bundle (i.e., bundle for
// targetLocale). If no providers are required for the bundle,
// none of its parents will require providers.
Class<? extends ResourceBundleProvider> type = strategy.getResourceBundleProviderType(baseName, targetLocale);
if (type != null) {
@SuppressWarnings("unchecked") ServiceLoader<ResourceBundleProvider> providers = (ServiceLoader<ResourceBundleProvider>) ServiceLoader.loadInstalled(type);
cacheKey.setProviders(providers);
}
List<Locale> candidateLocales = strategy.getCandidateLocales(baseName, targetLocale);
bundle = findBundleOf(cacheKey, strategy, baseName, candidateLocales, 0);
if (bundle == null) {
throwMissingResourceException(baseName, targetLocale, cacheKey.getCause());
}
return bundle;
}
use of java.util.spi.ResourceBundleProvider in project Bytecoder by mirkosertic.
the class ResourceBundle method loadBundle.
/*
* Loads a ResourceBundle in named modules
*/
private static ResourceBundle loadBundle(CacheKey cacheKey, List<String> formats, Control control, Module module, Module callerModule) {
String baseName = cacheKey.getName();
Locale targetLocale = cacheKey.getLocale();
ResourceBundle bundle = null;
if (cacheKey.hasProviders()) {
if (callerModule == module) {
bundle = loadBundleFromProviders(baseName, targetLocale, cacheKey.getProviders(), cacheKey);
} else {
// load from provider if the caller module has access to the
// service type and also declares `uses`
ClassLoader loader = getLoader(module);
Class<ResourceBundleProvider> svc = getResourceBundleProviderType(baseName, loader);
if (svc != null && Reflection.verifyModuleAccess(callerModule, svc) && callerModule.canUse(svc)) {
bundle = loadBundleFromProviders(baseName, targetLocale, cacheKey.getProviders(), cacheKey);
}
}
if (bundle != null) {
cacheKey.setFormat(UNKNOWN_FORMAT);
}
}
// look up module-local bundles or from the class path
if (bundle == null && !cacheKey.callerHasProvider()) {
for (String format : formats) {
try {
switch(format) {
case "java.class":
bundle = ResourceBundleProviderHelper.loadResourceBundle(callerModule, module, baseName, targetLocale);
break;
case "java.properties":
bundle = ResourceBundleProviderHelper.loadPropertyResourceBundle(callerModule, module, baseName, targetLocale);
break;
default:
throw new InternalError("unexpected format: " + format);
}
if (bundle != null) {
cacheKey.setFormat(format);
break;
}
} catch (LinkageError | Exception e) {
cacheKey.setCause(e);
}
}
}
return bundle;
}
Aggregations