mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
IDEA-343507 Add the ability to resolve bundles with custom locale
This allows for resolving bundles with a custom locale, especially in cases where the plugin context is not initialized yet. GitOrigin-RevId: 252e15e870d1ac6f573f94a6ffe6f524c25d4074
This commit is contained in:
committed by
intellij-monorepo-bot
parent
002690605c
commit
cc2fae82bb
@@ -27,7 +27,7 @@ import java.lang.reflect.Method;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class DynamicBundle extends AbstractBundle {
|
||||
private static final Logger LOG = Logger.getInstance(DynamicBundle.class);
|
||||
@@ -64,29 +64,29 @@ public class DynamicBundle extends AbstractBundle {
|
||||
return resolveResourceBundle(
|
||||
getBundleClassLoader(),
|
||||
baseLoader,
|
||||
loader -> {
|
||||
return super.findBundle(pathToBundle, loader, control, getLocale());
|
||||
}, pathToBundle
|
||||
(loader, locale) -> {
|
||||
return super.findBundle(pathToBundle, loader, control, locale);
|
||||
}, pathToBundle, getLocale()
|
||||
);
|
||||
}
|
||||
|
||||
private static @NotNull ResourceBundle resolveResourceBundle(
|
||||
@NotNull ClassLoader bundleClassLoader,
|
||||
@NotNull ClassLoader baseLoader,
|
||||
@NotNull Function<? super @NotNull ClassLoader, ? extends @NotNull ResourceBundle> bundleResolver,
|
||||
@NotNull String defaultPath
|
||||
@NotNull BiFunction<? super @NotNull ClassLoader, Locale, ? extends @NotNull ResourceBundle> bundleResolver,
|
||||
@NotNull String defaultPath,
|
||||
@NotNull Locale locale
|
||||
) {
|
||||
Path bundlePath = FileSystems.getDefault().getPath(defaultPath.replaceAll("\\.", "/"));
|
||||
ClassLoader pluginClassLoader = languagePluginClassLoader(bundleClassLoader);
|
||||
List<Path> paths = LocalizationUtil.Companion.getLocalizedPaths(bundlePath);
|
||||
ClassLoader pluginClassLoader = languagePluginClassLoader(bundleClassLoader, locale);
|
||||
List<Path> paths = LocalizationUtil.Companion.getLocalizedPaths(bundlePath, locale);
|
||||
Map<BundleOrder, ResourceBundle> bundleOrderMap = new HashMap<>();
|
||||
if (pluginClassLoader != null) {
|
||||
resolveBundleOrder(pluginClassLoader, true, bundlePath, paths, bundleOrderMap, bundleResolver);
|
||||
resolveBundleOrder(pluginClassLoader, true, bundlePath, paths, bundleOrderMap, bundleResolver, locale);
|
||||
}
|
||||
resolveBundleOrder(baseLoader, false, bundlePath, paths, bundleOrderMap, bundleResolver);
|
||||
resolveBundleOrder(baseLoader, false, bundlePath, paths, bundleOrderMap, bundleResolver, locale);
|
||||
reorderParents(bundleOrderMap);
|
||||
Optional<Map.Entry<BundleOrder, ResourceBundle>> resourceBundleEntry =
|
||||
bundleOrderMap.entrySet().stream().min(Map.Entry.comparingByKey());
|
||||
Optional<Map.Entry<BundleOrder, ResourceBundle>> resourceBundleEntry = bundleOrderMap.entrySet().stream().min(Map.Entry.comparingByKey());
|
||||
if (!resourceBundleEntry.isPresent()) {
|
||||
throw new RuntimeException("No such resource bundle: " + bundlePath);
|
||||
}
|
||||
@@ -96,12 +96,12 @@ public class DynamicBundle extends AbstractBundle {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
private static List<ResourceBundle> getBundlesFromLocalizationFolder(Path pathToBundle, ClassLoader loader) {
|
||||
List<Path> paths = LocalizationUtil.Companion.getFolderLocalizedPaths(pathToBundle);
|
||||
private static List<ResourceBundle> getBundlesFromLocalizationFolder(Path pathToBundle, ClassLoader loader, Locale locale) {
|
||||
List<Path> paths = LocalizationUtil.Companion.getFolderLocalizedPaths(pathToBundle, locale);
|
||||
List<ResourceBundle> resourceBundles = new ArrayList<>();
|
||||
for (Path path : paths) {
|
||||
try {
|
||||
ResourceBundle resourceBundle = bundleResolver(path.toString().replace('\\', '/')).apply(loader);
|
||||
ResourceBundle resourceBundle = bundleResolver(path.toString().replace('\\', '/')).apply(loader, locale);
|
||||
resourceBundles.add(resourceBundle);
|
||||
}
|
||||
catch (MissingResourceException e) {
|
||||
@@ -111,7 +111,7 @@ public class DynamicBundle extends AbstractBundle {
|
||||
return resourceBundles;
|
||||
}
|
||||
|
||||
private static @Nullable ClassLoader languagePluginClassLoader(@NotNull ClassLoader bundleClassLoader) {
|
||||
private static @Nullable ClassLoader languagePluginClassLoader(@NotNull ClassLoader bundleClassLoader, @NotNull Locale locale) {
|
||||
if (DefaultBundleService.isDefaultBundle()) {
|
||||
return null;
|
||||
}
|
||||
@@ -119,6 +119,10 @@ public class DynamicBundle extends AbstractBundle {
|
||||
if (langBundle == null) {
|
||||
return null;
|
||||
}
|
||||
if (!Objects.equals(locale.getLanguage(), getLocale().getLanguage()) ||
|
||||
(locale.getCountry() != null && !Objects.equals(locale.getCountry(), getLocale().getCountry()))) {
|
||||
return null;
|
||||
}
|
||||
PluginDescriptor pluginDescriptor = langBundle.pluginDescriptor;
|
||||
return pluginDescriptor == null ? bundleClassLoader
|
||||
: pluginDescriptor.getClassLoader();
|
||||
@@ -136,8 +140,9 @@ public class DynamicBundle extends AbstractBundle {
|
||||
Path pathToBundle,
|
||||
List<Path> orderedPaths,
|
||||
Map<BundleOrder, ResourceBundle> bundleOrderMap,
|
||||
@NotNull Function<? super @NotNull ClassLoader, ? extends @NotNull ResourceBundle> bundleResolver) {
|
||||
ResourceBundle bundle = bundleResolver.apply(loader);
|
||||
@NotNull BiFunction<? super @NotNull ClassLoader, Locale, ? extends @NotNull ResourceBundle> bundleResolver,
|
||||
@NotNull Locale locale) {
|
||||
ResourceBundle bundle = bundleResolver.apply(loader, locale);
|
||||
try {
|
||||
while (bundle != null) {
|
||||
putBundleOrder(bundle, bundleOrderMap, orderedPaths, isPluginClassLoader);
|
||||
@@ -147,7 +152,7 @@ public class DynamicBundle extends AbstractBundle {
|
||||
catch (Throwable throwable) {
|
||||
LOG.info(throwable);
|
||||
}
|
||||
for (ResourceBundle localizedBundle : getBundlesFromLocalizationFolder(pathToBundle, loader)) {
|
||||
for (ResourceBundle localizedBundle : getBundlesFromLocalizationFolder(pathToBundle, loader, locale)) {
|
||||
putBundleOrder(localizedBundle, bundleOrderMap, orderedPaths, isPluginClassLoader);
|
||||
}
|
||||
}
|
||||
@@ -279,6 +284,12 @@ public class DynamicBundle extends AbstractBundle {
|
||||
.computeIfAbsent(pathToBundle, __ -> resolveResourceBundle(loader, pathToBundle));
|
||||
}
|
||||
|
||||
public static @NotNull ResourceBundle getResourceBundle(@NotNull ClassLoader loader, @NotNull @NonNls String pathToBundle, @NotNull Locale locale) {
|
||||
return (DefaultBundleService.isDefaultBundle() ? ourDefaultCache : ourCache)
|
||||
.computeIfAbsent(loader, __ -> CollectionFactory.createConcurrentSoftValueMap())
|
||||
.computeIfAbsent(pathToBundle, __ -> resolveResourceBundle(loader, pathToBundle, locale));
|
||||
}
|
||||
|
||||
public static @Nullable ResourceBundle getPluginBundle(@NotNull PluginDescriptor pluginDescriptor) {
|
||||
ClassLoader classLoader = pluginDescriptor.getPluginClassLoader();
|
||||
String baseName = pluginDescriptor.getResourceBundleBaseName();
|
||||
@@ -289,14 +300,24 @@ public class DynamicBundle extends AbstractBundle {
|
||||
return resolveResourceBundleWithFallback(
|
||||
() -> resolveResourceBundle(
|
||||
DynamicBundle.class.getClassLoader(),
|
||||
loader, bundleResolver(pathToBundle), pathToBundle
|
||||
loader, bundleResolver(pathToBundle), pathToBundle, getLocale()
|
||||
),
|
||||
loader, pathToBundle
|
||||
);
|
||||
}
|
||||
|
||||
private static @NotNull Function<@NotNull ClassLoader, @NotNull ResourceBundle> bundleResolver(@NonNls @NotNull String pathToBundle) {
|
||||
return l -> AbstractBundle.resolveBundle(l, getLocale(), pathToBundle);
|
||||
private static @NotNull ResourceBundle resolveResourceBundle(@NotNull ClassLoader loader, @NonNls @NotNull String pathToBundle, @NotNull Locale locale) {
|
||||
return resolveResourceBundleWithFallback(
|
||||
() -> resolveResourceBundle(
|
||||
DynamicBundle.class.getClassLoader(),
|
||||
loader, bundleResolver(pathToBundle), pathToBundle, locale
|
||||
),
|
||||
loader, pathToBundle
|
||||
);
|
||||
}
|
||||
|
||||
private static @NotNull BiFunction<@NotNull ClassLoader, @NotNull Locale, @NotNull ResourceBundle> bundleResolver(@NonNls @NotNull String pathToBundle) {
|
||||
return (loader, locale) -> resolveBundle(loader, locale, pathToBundle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,8 +46,10 @@ class LocalizationUtil {
|
||||
return result
|
||||
}
|
||||
|
||||
fun getResourceAsStream(defaultLoader: ClassLoader?, path: Path): InputStream? {
|
||||
val localizedPaths = getLocalizedPaths(path)
|
||||
@JvmOverloads
|
||||
fun getResourceAsStream(defaultLoader: ClassLoader?, path: Path, specialLocale: Locale? = null): InputStream? {
|
||||
val locale = specialLocale ?: getLocale()
|
||||
val localizedPaths = getLocalizedPaths(path, locale)
|
||||
for (localizedPath in localizedPaths) {
|
||||
val pathString = localizedPath.pathString.replace('\\', '/')
|
||||
getPluginClassLoader()?.getResourceAsStream(pathString)?.let { return it }
|
||||
@@ -56,31 +58,35 @@ class LocalizationUtil {
|
||||
return null
|
||||
}
|
||||
|
||||
fun getLocalizedPaths(path: Path): List<Path> {
|
||||
@JvmOverloads
|
||||
fun getLocalizedPaths(path: Path, specialLocale: Locale? = null): List<Path> {
|
||||
val locale = specialLocale ?: getLocale()
|
||||
val result = mutableListOf<Path>()
|
||||
//localizations/zh/CN/inspectionDescriptions/name.html
|
||||
result.add(convertPathToLocalizationFolderUsage(path, getLocale(), true))
|
||||
result.add(convertPathToLocalizationFolderUsage(path, locale, true))
|
||||
|
||||
//inspectionDescriptions/name_zh_CN.html
|
||||
result.add(convertPathToLocaleSuffixUsage(path, getLocale(), true))
|
||||
result.add(convertPathToLocaleSuffixUsage(path, locale, true))
|
||||
|
||||
//localizations/zh/inspectionDescriptions/name.html
|
||||
result.add(convertPathToLocalizationFolderUsage(path, getLocale(), false))
|
||||
result.add(convertPathToLocalizationFolderUsage(path, locale, false))
|
||||
|
||||
//inspectionDescriptions/name_zh.html
|
||||
result.add(convertPathToLocaleSuffixUsage(path, getLocale(), false))
|
||||
result.add(convertPathToLocaleSuffixUsage(path, locale, false))
|
||||
//inspectionDescriptions/name.html
|
||||
result.add(path)
|
||||
return result
|
||||
}
|
||||
|
||||
fun getFolderLocalizedPaths(path: Path): List<Path> {
|
||||
@JvmOverloads
|
||||
fun getFolderLocalizedPaths(path: Path, specialLocale: Locale? = null): List<Path> {
|
||||
val locale = specialLocale ?: getLocale()
|
||||
val result = mutableListOf<Path>()
|
||||
//localizations/zh/CN/inspectionDescriptions/name.html
|
||||
result.add(convertPathToLocalizationFolderUsage(path, getLocale(), true))
|
||||
result.add(convertPathToLocalizationFolderUsage(path, locale, true))
|
||||
|
||||
//localizations/zh/inspectionDescriptions/name.html
|
||||
result.add(convertPathToLocalizationFolderUsage(path, getLocale(), false))
|
||||
result.add(convertPathToLocalizationFolderUsage(path, locale, false))
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user