IJPL-159035 don't use java Path for resource paths

GitOrigin-RevId: 734c2c1d9c7a1acfce786b2680adc9235f387329
This commit is contained in:
Vladimir Krivosheev
2024-07-30 16:22:57 +02:00
committed by intellij-monorepo-bot
parent fce9ac0789
commit 024dc64165
10 changed files with 83 additions and 116 deletions

View File

@@ -22,7 +22,6 @@ import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -202,12 +201,15 @@ public abstract class InspectionToolWrapper<T extends InspectionProfileEntry, E
private @Nullable InputStream getDescriptionStream() {
Application app = ApplicationManager.getApplication();
Path path = Path.of(INSPECTION_DESCRIPTIONS_FOLDER).resolve(getDescriptionFileName());
String path = INSPECTION_DESCRIPTIONS_FOLDER + "/" + getDescriptionFileName();
ClassLoader classLoader;
if (myEP == null || app.isUnitTestMode() || app.isHeadlessEnvironment()) {
return LocalizationUtil.INSTANCE.getResourceAsStream(getDescriptionContextClass().getClassLoader(), path);
classLoader = getDescriptionContextClass().getClassLoader();
}
return LocalizationUtil.INSTANCE.getResourceAsStream(myEP.getPluginDescriptor().getPluginClassLoader(), path);
else {
classLoader = myEP.getPluginDescriptor().getPluginClassLoader();
}
return LocalizationUtil.INSTANCE.getResourceAsStream(classLoader, path, null);
}
private @NotNull String getDescriptionFileName() {

View File

@@ -8,6 +8,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.PluginAware;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.DefaultBundleService;
import com.intellij.util.ReflectionUtil;
@@ -21,8 +22,6 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.function.BiFunction;
@@ -83,9 +82,9 @@ public class DynamicBundle extends AbstractBundle {
@NotNull String defaultPath,
@NotNull Locale locale,
@NotNull BiFunction<? super @NotNull ClassLoader, ? super Locale, ? extends @NotNull ResourceBundle> bundleResolver) {
Path bundlePath = FileSystems.getDefault().getPath(FileUtil.toCanonicalPath(defaultPath, '.'));
String bundlePath = FileUtilRt.toCanonicalPath(defaultPath, '.', true);
ClassLoader pluginClassLoader = DefaultBundleService.isDefaultBundle() ? null: LocalizationUtil.INSTANCE.getPluginClassLoader(bundleClassLoader, locale);
List<Path> paths = LocalizationUtil.INSTANCE.getLocalizedPathsWithDefault(bundlePath, locale);
List<String> paths = LocalizationUtil.INSTANCE.getLocalizedPathsWithDefault(bundlePath, locale);
Map<LocalizationOrder, ResourceBundle> bundleOrderMap = new HashMap<>();
if (pluginClassLoader != null) {
try {
@@ -107,13 +106,12 @@ public class DynamicBundle extends AbstractBundle {
return bundle;
}
private static @NotNull List<ResourceBundle> getBundlesFromLocalizationFolder(@NotNull Path pathToBundle, ClassLoader loader, @NotNull Locale locale) {
List<Path> paths = LocalizationUtil.INSTANCE.getFolderLocalizedPaths(pathToBundle, locale);
private static @NotNull List<ResourceBundle> getBundlesFromLocalizationFolder(@NotNull String pathToBundle, ClassLoader loader, @NotNull Locale locale) {
List<String> paths = LocalizationUtil.INSTANCE.getFolderLocalizedPaths(pathToBundle, locale);
List<ResourceBundle> resourceBundles = new ArrayList<>();
for (Path path : paths) {
for (String path : paths) {
try {
ResourceBundle resourceBundle = AbstractBundleKt._doResolveBundle(loader, locale, FileUtil.toSystemIndependentName(path.toString()));
resourceBundles.add(resourceBundle);
resourceBundles.add(AbstractBundleKt._doResolveBundle(loader, locale, path));
}
catch (MissingResourceException ignored) { }
}
@@ -130,8 +128,8 @@ public class DynamicBundle extends AbstractBundle {
}
private static void resolveBundleOrder(@NotNull ClassLoader loader,
@NotNull Path pathToBundle,
@NotNull List<? extends Path> orderedPaths,
@NotNull String pathToBundle,
@NotNull List<String> orderedPaths,
@NotNull Map<? super LocalizationOrder, ? super ResourceBundle> bundleOrderMap,
@NotNull BiFunction<? super @NotNull ClassLoader, ? super Locale, ? extends @NotNull ResourceBundle> bundleResolver,
@NotNull Locale locale) {
@@ -152,16 +150,15 @@ public class DynamicBundle extends AbstractBundle {
private static void putBundleOrder(@NotNull ResourceBundle bundle,
@NotNull Map<? super LocalizationOrder, ? super ResourceBundle> bundleOrderMap,
@NotNull List<? extends Path> orderedPaths) {
@NotNull List<String> orderedPaths) {
String bundlePath = FileUtil.toCanonicalPath(bundle.getBaseBundleName(), '.');
if (!bundle.getLocale().toString().isEmpty()) {
bundlePath += "_" + bundle.getLocale().toString();
}
Path path = FileSystems.getDefault().getPath(bundlePath);
LocalizationOrder localizationOrder = LocalizationOrder.Companion.getLocalizationOrder(orderedPaths, path);
LocalizationOrder localizationOrder = LocalizationOrder.Companion.getLocalizationOrder(orderedPaths, bundlePath);
if (localizationOrder == null) {
LOG.debug("Order cannot be defined for the bundle: " + path +
LOG.debug("Order cannot be defined for the bundle: " + bundlePath +
"; Current locale: " + getLocale() +
"; Paths for locale: " + orderedPaths);
return;

View File

@@ -2,7 +2,6 @@
package com.intellij.l10n
import org.jetbrains.annotations.ApiStatus
import java.nio.file.Path
@ApiStatus.Internal
enum class LocalizationOrder {
@@ -14,7 +13,7 @@ enum class LocalizationOrder {
DEFAULT_PLATFORM; //name.properties
companion object {
fun getLocalizationOrder(orderedPaths: List<Path?>, bundlePath: Path): LocalizationOrder? {
fun getLocalizationOrder(orderedPaths: List<String>, bundlePath: String): LocalizationOrder? {
return when (orderedPaths.size) {
1 -> DEFAULT_PLATFORM
3 -> {

View File

@@ -5,18 +5,15 @@ import com.intellij.DynamicBundle
import com.intellij.diagnostic.LoadingState
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.util.PathUtilRt
import org.jetbrains.annotations.ApiStatus.Internal
import java.io.IOException
import java.io.InputStream
import java.nio.file.Path
import java.nio.file.Paths
import java.util.*
import kotlin.io.path.Path
import kotlin.io.path.extension
import kotlin.io.path.invariantSeparatorsPathString
import kotlin.io.path.nameWithoutExtension
import kotlin.io.path.pathString
object LocalizationUtil {
private const val LOCALIZATION_FOLDER_NAME: String = "localization"
@@ -47,10 +44,7 @@ object LocalizationUtil {
return locale
}
fun getLocaleOrNullForDefault(): Locale? {
val locale = getLocale()
return if (locale.language == defaultLocale.language) null else locale
}
fun getLocaleOrNullForDefault(): Locale? = getLocale().takeIf { it.language != defaultLocale.language }
@Internal
@JvmOverloads
@@ -63,23 +57,23 @@ object LocalizationUtil {
return langBundle.pluginDescriptor?.classLoader ?: defaultLoader
}
private fun convertToLocalizationFolderUsage(paths: Path, locale: Locale, withRegion: Boolean): Path {
var result = Paths.get(LOCALIZATION_FOLDER_NAME).resolve(locale.language)
private fun convertToLocalizationFolderUsage(p: String, locale: Locale, withRegion: Boolean): String {
val result = StringBuilder().append(LOCALIZATION_FOLDER_NAME).append('/').append(locale.language)
if (withRegion && locale.country.isNotEmpty()) {
result = result.resolve(locale.country)
result.append('/').append(locale.country)
}
result = result.resolve(paths)
return result
result.append('/').append(p)
return result.toString()
}
private fun convertPathToLocaleSuffixUsage(file: Path, locale: Locale?, withRegion: Boolean): Path {
private fun convertPathToLocaleSuffixUsage(file: String, locale: Locale?, withRegion: Boolean): String {
if (locale == null) {
return file
}
val fileName = StringBuilder(file.nameWithoutExtension)
val extension = file.extension
val foldersPath = file.parent ?: Paths.get("")
val pathFileName = PathUtilRt.getFileName(file)
val fileName = StringBuilder().append(PathUtilRt.getParentPath(file)).append('/').append(FileUtilRt.getNameWithoutExtension(pathFileName))
val extension = FileUtilRt.getExtension(pathFileName)
val language = locale.language
if (!language.isEmpty()) {
fileName.append('_').append(language)
@@ -91,69 +85,52 @@ object LocalizationUtil {
if (extension.isNotEmpty()) {
fileName.append('.').append(extension)
}
return foldersPath.resolve(fileName.toString())
return fileName.toString()
}
@Internal
@JvmOverloads
fun getResourceAsStream(defaultLoader: ClassLoader?, path: Path, specialLocale: Locale? = null): InputStream? {
val locale = specialLocale ?: getLocale()
for (localizedPath in getLocalizedPaths(path, locale)) {
defaultLoader?.getResourceAsStream(localizedPath.invariantSeparatorsPathString)?.let { return it }
fun getResourceAsStream(classLoader: ClassLoader?, path: String, specialLocale: Locale? = null): InputStream? {
if (classLoader != null) {
try {
val locale = specialLocale ?: getLocaleOrNullForDefault()
for (localizedPath in getLocalizedPaths(path, locale)) {
classLoader.getResourceAsStream(localizedPath)?.let { return it }
}
}
catch (e: IOException) {
thisLogger().error("Cannot find localized resource: $path", e)
}
}
val resourcePath = path.pathString
val pureResourcePath = FileUtil.toSystemIndependentName(resourcePath)
return getPluginClassLoader()?.getResourceAsStream(resourcePath)
?: getPluginClassLoader()?.getResourceAsStream(pureResourcePath)
?: defaultLoader?.getResourceAsStream(resourcePath)
?: defaultLoader?.getResourceAsStream(pureResourcePath)
return getPluginClassLoader()?.getResourceAsStream(path) ?: classLoader?.getResourceAsStream(path)
}
@Internal
@JvmOverloads
fun getResourceAsStream(defaultLoader: ClassLoader?, path: String, specialLocale: Locale? = null): InputStream? {
val locale = specialLocale ?: getLocale()
for (localizedPath in getLocalizedPaths(Paths.get(path), locale)) {
defaultLoader?.getResourceAsStream(localizedPath.invariantSeparatorsPathString)?.let { return it }
}
return getPluginClassLoader()?.getResourceAsStream(path) ?: defaultLoader?.getResourceAsStream(path)
fun getLocalizedPathsWithDefault(path: String, specialLocale: Locale? = null): List<String> {
return getLocalizedPaths(path, specialLocale).toMutableList().plusElement(path).distinct()
}
@Internal
@JvmOverloads
fun getLocalizedPathsWithDefault(path: Path, specialLocale: Locale? = null): List<Path> {
val locale = specialLocale ?: getLocale()
return getLocalizedPaths(path, locale).toMutableList().plusElement(path).distinct()
}
@Internal
@JvmOverloads
fun getLocalizedPaths(path: Path, specialLocale: Locale? = null): Collection<Path> {
val locale = specialLocale ?: getLocale()
if (locale == Locale.ROOT) {
fun getLocalizedPaths(path: String, specialLocale: Locale? = null): Collection<String> {
val locale = specialLocale ?: getLocaleOrNullForDefault()
if (locale == null || locale == Locale.ROOT) {
return emptyList()
}
return linkedSetOf(
//localizations/zh/CN/inspectionDescriptions/name.html
convertToLocalizationFolderUsage(paths = path, locale = locale, withRegion = true),
convertToLocalizationFolderUsage(p = path, locale = locale, withRegion = true),
//inspectionDescriptions/name_zh_CN.html
convertPathToLocaleSuffixUsage(file = path, locale = locale, withRegion = true),
//localizations/zh/inspectionDescriptions/name.html
convertToLocalizationFolderUsage(paths = path, locale = locale, withRegion = false),
convertToLocalizationFolderUsage(p = path, locale = locale, withRegion = false),
//inspectionDescriptions/name_zh.html
convertPathToLocaleSuffixUsage(file = path, locale = locale, withRegion = false),
)
}
@Internal
@JvmOverloads
fun getLocalizedPathStrings(path: String, specialLocale: Locale? = null): List<String> {
return getLocalizedPaths(Path(path), specialLocale).map { FileUtil.toSystemIndependentName(it.pathString) }
}
@Internal
fun getLocalizationSuffixes(specialLocale: Locale? = null): List<String> {
@@ -170,7 +147,7 @@ object LocalizationUtil {
@Internal
@JvmOverloads
fun getFolderLocalizedPaths(path: Path, specialLocale: Locale? = null): List<Path> {
fun getFolderLocalizedPaths(path: String, specialLocale: Locale? = null): List<String> {
val locale = specialLocale ?: getLocaleOrNullForDefault() ?: return emptyList()
return listOf(
//localizations/zh/CN/inspectionDescriptions/name.html
@@ -182,14 +159,15 @@ object LocalizationUtil {
@Internal
@JvmOverloads
fun getSuffixLocalizedPaths(path: Path, specialLocale: Locale? = null): List<String> {
val locale = specialLocale ?: getLocale()
fun getSuffixLocalizedPaths(path: String, specialLocale: Locale? = null): List<String> {
val locale = specialLocale ?: getLocaleOrNullForDefault()
return setOf(
//inspectionDescriptions/name_zh_CN.html
convertPathToLocaleSuffixUsage(path, locale, true),
convertPathToLocaleSuffixUsage(file = path, locale, true),
//inspectionDescriptions/name_zh.html
convertPathToLocaleSuffixUsage(path, locale, false))
convertPathToLocaleSuffixUsage(file = path, locale, false),
)
.map { FileUtil.toSystemIndependentName(it.toString()) }
}

View File

@@ -1,31 +1,18 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.intention.impl.config
import com.intellij.l10n.LocalizationUtil.getResourceAsStream
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.util.ResourceUtil
import com.intellij.l10n.LocalizationUtil
import java.io.IOException
internal data class ResourceTextDescriptor(
private val loader: ClassLoader,
private val loader: ClassLoader?,
private val resourcePath: String,
) : TextDescriptor {
@Throws(IOException::class)
override fun getText(): String {
val inputStream = getResourceAsStream(loader, resourcePath)
if (inputStream != null) {
try {
inputStream.use {
return ResourceUtil.loadText(inputStream)
}
}
catch (e: IOException) {
thisLogger().error("Cannot find localized resource: $resourcePath", e)
}
}
val stream = loader.getResourceAsStream(resourcePath) ?: throw IOException("Resource not found: $resourcePath; loader: $loader")
return ResourceUtil.loadText(stream)
val stream = LocalizationUtil.getResourceAsStream(loader, resourcePath)
?: throw IOException("Resource not found: $resourcePath; loader: $loader")
return stream.use { it.readAllBytes().decodeToString() }
}
override fun getFileName(): String {

View File

@@ -374,12 +374,13 @@ private fun loadLocalizedContent(classLoader: ClassLoader, root: Any, path: Stri
var result: String?
val locale = LocalizationUtil.getLocaleOrNullForDefault()
if (locale != null) {
val contentPath = Path.of(path)
//loading from source files with localization folder/suffix
val localizedPaths = LocalizationUtil.getLocalizedPaths(contentPath).map { it.invariantSeparatorsPathString }
//loading from source files with localization folder/suffix
val localizedPaths = LocalizationUtil.getLocalizedPaths(path)
for (localizedPath in localizedPaths) {
result = loadFileContent(classLoader, root, localizedPath)
if (!result.isNullOrEmpty()) return result
if (!result.isNullOrEmpty()) {
return result
}
}
//loading from localization plugin
result = LocalizationUtil.getPluginClassLoader()?.let {
@@ -397,7 +398,10 @@ private fun loadFileContent(classLoader: ClassLoader, root: Any, path: String):
var result: String? = null
try {
result = ResourceUtil.getResourceAsBytesSafely(path, classLoader)?.toString(StandardCharsets.UTF_8)
if (!result.isNullOrEmpty()) return result
if (!result.isNullOrEmpty()) {
return result
}
when (root) {
is URL -> {
val url = URL(root.protocol, root.host, root.port, root.path.replace(DEFAULT_TEMPLATES_ROOT, path))

View File

@@ -87,10 +87,11 @@ public final class ConsentOptions implements ModificationTracker {
@Override
public @Nullable String readLocalizedBundledConsents() {
if (getCurrentLocale() == getDefaultLocale()) return null;
String path = getBundledResourcePath();
List<String> localizedPaths = LocalizationUtil.INSTANCE.getLocalizedPathStrings(path, getCurrentLocale());
for (String localizedPath : localizedPaths) {
if (getCurrentLocale() == getDefaultLocale()) {
return null;
}
for (String localizedPath : LocalizationUtil.INSTANCE.getLocalizedPaths(getBundledResourcePath(), getCurrentLocale())) {
String loadedText = loadText(ConsentOptions.class.getClassLoader().getResourceAsStream(localizedPath));
if (!loadedText.isEmpty()) {
return loadedText;

View File

@@ -99,7 +99,7 @@ public final class EndUserAgreement {
String docName = getDocumentName();
Document defaultDocument = loadDocument(docName);
Locale locale = Locale.getDefault();
List<String> localizedDocsNames = LocalizationUtil.INSTANCE.getSuffixLocalizedPaths(Path.of(docName), locale);
List<String> localizedDocsNames = LocalizationUtil.INSTANCE.getSuffixLocalizedPaths(docName, locale);
Document document;
for (String localizedDocName : localizedDocsNames) {
@@ -120,7 +120,7 @@ public final class EndUserAgreement {
public static void updateCachedContentToLatestBundledVersion() {
String docName = getDocumentName();
Locale locale = Locale.getDefault();
List<String> localizedDocsNames = LocalizationUtil.INSTANCE.getSuffixLocalizedPaths(Path.of(docName), locale);
List<String> localizedDocsNames = LocalizationUtil.INSTANCE.getSuffixLocalizedPaths(docName, locale);
for (String localizedDocName : localizedDocsNames) {
updateCachedContentToLatestBundledVersion(localizedDocName);
}

View File

@@ -295,7 +295,7 @@ class SearchableOptionsRegistrarImpl : SearchableOptionsRegistrar() {
}
@Synchronized
fun getAcceptableDescriptions(prefix: String?): Set<OptionDescription>? {
fun getAcceptableDescriptions(prefix: String?): MutableSet<OptionDescription>? {
if (prefix == null || !isInitialized()) {
return null
}

View File

@@ -39,7 +39,6 @@ import java.nio.file.Files
import java.nio.file.Path
import javax.swing.Icon
import javax.swing.text.StyleConstants
import kotlin.io.path.invariantSeparatorsPathString
private val LOG = logger<TipUtils>()
@@ -208,7 +207,7 @@ private fun getTipRetrievers(tip: TipAndTrickBean): TipRetrieversInfo {
private fun getLocalizationTipRetrievers(loader: ClassLoader): List<TipRetriever> {
val result = mutableListOf<TipRetriever>()
val folderPaths = LocalizationUtil.getFolderLocalizedPaths(Path.of(tipDirectory)).map { it.invariantSeparatorsPathString }
val folderPaths = LocalizationUtil.getFolderLocalizedPaths(tipDirectory)
val suffixes = LocalizationUtil.getLocalizationSuffixes()
//folder paths and suffix paths should have the same size, because their elements depend on locale (if it contains a region or not)
for (i in folderPaths.indices) {