在 LocaleUtils 中添加更多工具方法 (#4390)
This commit is contained in:
@@ -22,22 +22,19 @@ import javafx.beans.property.SimpleObjectProperty;
|
|||||||
import javafx.scene.text.Font;
|
import javafx.scene.text.Font;
|
||||||
import org.jackhuang.hmcl.Metadata;
|
import org.jackhuang.hmcl.Metadata;
|
||||||
import org.jackhuang.hmcl.util.Lazy;
|
import org.jackhuang.hmcl.util.Lazy;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
|
||||||
import org.jackhuang.hmcl.util.i18n.DefaultResourceBundleControl;
|
|
||||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||||
|
import org.jackhuang.hmcl.util.i18n.LocaleUtils;
|
||||||
import org.jackhuang.hmcl.util.io.JarUtils;
|
import org.jackhuang.hmcl.util.io.JarUtils;
|
||||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||||
import org.jackhuang.hmcl.util.platform.SystemUtils;
|
import org.jackhuang.hmcl.util.platform.SystemUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
@@ -145,47 +142,32 @@ public final class FontManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Font tryLoadLocalizedFont(Path dir) {
|
private static Font tryLoadLocalizedFont(Path dir) {
|
||||||
if (!Files.isDirectory(dir))
|
Map<String, Map<String, Path>> fontFiles = LocaleUtils.findAllLocalizedFiles(dir, "font", Set.of(FONT_EXTENSIONS));
|
||||||
|
if (fontFiles.isEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
try (Stream<Path> list = Files.list(dir)) {
|
List<Locale> candidateLocales = I18n.getLocale().getCandidateLocales();
|
||||||
Map<String, Path> map = new HashMap<>();
|
|
||||||
|
|
||||||
Set<String> extensions = Set.of(FONT_EXTENSIONS);
|
for (Locale locale : candidateLocales) {
|
||||||
list.forEach(file -> {
|
Map<String, Path> extToFiles = fontFiles.get(LocaleUtils.toLanguageKey(locale));
|
||||||
if (Files.isRegularFile(file)) {
|
if (extToFiles != null) {
|
||||||
String fileName = file.getFileName().toString();
|
for (String ext : FONT_EXTENSIONS) {
|
||||||
String extension = StringUtils.substringAfterLast(fileName, '.');
|
Path fontFile = extToFiles.get(ext);
|
||||||
|
if (fontFile != null) {
|
||||||
|
LOG.info("Load font file: " + fontFile);
|
||||||
|
try {
|
||||||
|
Font font = Font.loadFont(
|
||||||
|
fontFile.toAbsolutePath().normalize().toUri().toURL().toExternalForm(),
|
||||||
|
DEFAULT_FONT_SIZE);
|
||||||
|
if (font != null)
|
||||||
|
return font;
|
||||||
|
} catch (MalformedURLException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
if (fileName.startsWith("font") && extensions.contains(extension)) {
|
LOG.warning("Failed to load font " + fontFile);
|
||||||
map.put(fileName.substring(0, fileName.length() - extension.length() - 1), file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
List<Locale> candidateLocales = I18n.getLocale().getCandidateLocales();
|
|
||||||
|
|
||||||
for (Locale locale : candidateLocales) {
|
|
||||||
String key = DefaultResourceBundleControl.INSTANCE.toBundleName("font", locale);
|
|
||||||
|
|
||||||
Path path = map.get(key);
|
|
||||||
if (path != null) {
|
|
||||||
LOG.info("Load font file: " + path);
|
|
||||||
try {
|
|
||||||
Font font = Font.loadFont(
|
|
||||||
path.toAbsolutePath().normalize().toUri().toURL().toExternalForm(),
|
|
||||||
DEFAULT_FONT_SIZE);
|
|
||||||
if (font != null)
|
|
||||||
return font;
|
|
||||||
} catch (MalformedURLException ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.warning("Failed to load font " + path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.warning("Failed to load font " + dir, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -20,7 +20,12 @@ package org.jackhuang.hmcl.util.i18n;
|
|||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
||||||
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale;
|
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale;
|
||||||
|
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -60,7 +65,48 @@ public final class I18n {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getDisplaySelfVersion(RemoteVersion version) {
|
public static String getDisplaySelfVersion(RemoteVersion version) {
|
||||||
return locale.getDisplaySelfVersion(version);
|
if (locale.getLocale().getLanguage().equals("lzh")) {
|
||||||
|
if (version instanceof GameRemoteVersion)
|
||||||
|
return WenyanUtils.translateGameVersion(GameVersionNumber.asGameVersion(version.getSelfVersion()));
|
||||||
|
else
|
||||||
|
return WenyanUtils.translateGenericVersion(version.getSelfVersion());
|
||||||
|
}
|
||||||
|
return version.getSelfVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find the builtin localized resource with given name and suffix.
|
||||||
|
///
|
||||||
|
/// For example, if the current locale is `zh-CN`, when calling `getBuiltinResource("assets.lang.foo", "json")`,
|
||||||
|
/// this method will look for the following built-in resources in order:
|
||||||
|
///
|
||||||
|
/// - `assets/lang/foo_zh_Hans_CN.json`
|
||||||
|
/// - `assets/lang/foo_zh_Hans.json`
|
||||||
|
/// - `assets/lang/foo_zh_CN.json`
|
||||||
|
/// - `assets/lang/foo_zh.json`
|
||||||
|
/// - `assets/lang/foo.json`
|
||||||
|
///
|
||||||
|
/// This method will return the first found resource;
|
||||||
|
/// if none of the above resources exist, it returns `null`.
|
||||||
|
public static @Nullable URL getBuiltinResource(String name, String suffix) {
|
||||||
|
var control = DefaultResourceBundleControl.INSTANCE;
|
||||||
|
var classLoader = I18n.class.getClassLoader();
|
||||||
|
for (Locale locale : locale.getCandidateLocales()) {
|
||||||
|
String resourceName = control.toResourceName(control.toBundleName(name, locale), suffix);
|
||||||
|
URL input = classLoader.getResource(resourceName);
|
||||||
|
if (input != null)
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @see [#getBuiltinResource(String, String) ]
|
||||||
|
public static @Nullable InputStream getBuiltinResourceAsStream(String name, String suffix) {
|
||||||
|
URL resource = getBuiltinResource(name, suffix);
|
||||||
|
try {
|
||||||
|
return resource != null ? resource.openStream() : null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getWikiLink(GameRemoteVersion remoteVersion) {
|
public static String getWikiLink(GameRemoteVersion remoteVersion) {
|
||||||
|
|||||||
@@ -20,14 +20,9 @@ package org.jackhuang.hmcl.util.i18n;
|
|||||||
import com.google.gson.annotations.JsonAdapter;
|
import com.google.gson.annotations.JsonAdapter;
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
|
||||||
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
@@ -199,16 +194,6 @@ public final class Locales {
|
|||||||
return formatter.format(time);
|
return formatter.format(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDisplaySelfVersion(RemoteVersion version) {
|
|
||||||
if (locale.getLanguage().equals("lzh")) {
|
|
||||||
if (version instanceof GameRemoteVersion)
|
|
||||||
return WenyanUtils.translateGameVersion(GameVersionNumber.asGameVersion(version.getSelfVersion()));
|
|
||||||
else
|
|
||||||
return WenyanUtils.translateGenericVersion(version.getSelfVersion());
|
|
||||||
}
|
|
||||||
return version.getSelfVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFcMatchPattern() {
|
public String getFcMatchPattern() {
|
||||||
String language = locale.getLanguage();
|
String language = locale.getLanguage();
|
||||||
String region = locale.getCountry();
|
String region = locale.getCountry();
|
||||||
@@ -244,31 +229,6 @@ public final class Locales {
|
|||||||
return region.isEmpty() ? language : language + "-" + region;
|
return region.isEmpty() ? language : language + "-" + region;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the builtin localized resource with given name and suffix.
|
|
||||||
///
|
|
||||||
/// For example, if the current locale is `zh-CN`, when calling `findBuiltinResource("assets.lang.foo", "json")`,
|
|
||||||
/// this method will look for the following built-in resources in order:
|
|
||||||
///
|
|
||||||
/// - `assets/lang/foo_zh_Hans_CN.json`
|
|
||||||
/// - `assets/lang/foo_zh_Hans.json`
|
|
||||||
/// - `assets/lang/foo_zh_CN.json`
|
|
||||||
/// - `assets/lang/foo_zh.json`
|
|
||||||
/// - `assets/lang/foo.json`
|
|
||||||
///
|
|
||||||
/// This method will open and return the first found resource;
|
|
||||||
/// if none of the above resources exist, it returns `null`.
|
|
||||||
public @Nullable InputStream findBuiltinResource(String name, String suffix) {
|
|
||||||
var control = DefaultResourceBundleControl.INSTANCE;
|
|
||||||
var classLoader = Locales.class.getClassLoader();
|
|
||||||
for (Locale locale : getCandidateLocales()) {
|
|
||||||
String resourceName = control.toResourceName(control.toBundleName(name, locale), suffix);
|
|
||||||
InputStream input = classLoader.getResourceAsStream(resourceName);
|
|
||||||
if (input != null)
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSameLanguage(SupportedLocale other) {
|
public boolean isSameLanguage(SupportedLocale other) {
|
||||||
return (this.getLocale().getLanguage().equals(other.getLocale().getLanguage()))
|
return (this.getLocale().getLanguage().equals(other.getLocale().getLanguage()))
|
||||||
|| (LocaleUtils.isChinese(this.getLocale()) && LocaleUtils.isChinese(other.getLocale()));
|
|| (LocaleUtils.isChinese(this.getLocale()) && LocaleUtils.isChinese(other.getLocale()));
|
||||||
|
|||||||
@@ -30,4 +30,5 @@ dependencies {
|
|||||||
compileOnlyApi(libs.jetbrains.annotations)
|
compileOnlyApi(libs.jetbrains.annotations)
|
||||||
|
|
||||||
testImplementation(libs.jna.platform)
|
testImplementation(libs.jna.platform)
|
||||||
|
testImplementation(libs.jimfs)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,34 +17,44 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.i18n;
|
package org.jackhuang.hmcl.util.i18n;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.io.IOException;
|
||||||
import java.util.Locale;
|
import java.nio.file.Files;
|
||||||
import java.util.Set;
|
import java.nio.file.Path;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Glavo
|
* @author Glavo
|
||||||
*/
|
*/
|
||||||
public class LocaleUtils {
|
public final class LocaleUtils {
|
||||||
|
|
||||||
public static final Locale SYSTEM_DEFAULT = Locale.getDefault();
|
public static final Locale SYSTEM_DEFAULT = Locale.getDefault();
|
||||||
|
|
||||||
public static final Locale LOCALE_ZH_HANS = Locale.forLanguageTag("zh-Hans");
|
public static final Locale LOCALE_ZH_HANS = Locale.forLanguageTag("zh-Hans");
|
||||||
public static final Locale LOCALE_ZH_HANT = Locale.forLanguageTag("zh-Hant");
|
public static final Locale LOCALE_ZH_HANT = Locale.forLanguageTag("zh-Hant");
|
||||||
|
|
||||||
|
public static final String DEFAULT_LANGUAGE_KEY = "default";
|
||||||
|
|
||||||
|
/// Convert a locale to the language key.
|
||||||
|
///
|
||||||
|
/// The language key is in the format of BCP 47 language tag.
|
||||||
|
/// If the locale is the default locale (language is empty), "default" will be returned.
|
||||||
public static String toLanguageKey(Locale locale) {
|
public static String toLanguageKey(Locale locale) {
|
||||||
if (locale.getLanguage().isEmpty())
|
return locale.getLanguage().isEmpty()
|
||||||
return "default";
|
? DEFAULT_LANGUAGE_KEY
|
||||||
else
|
: locale.stripExtensions().toLanguageTag();
|
||||||
return locale.toLanguageTag();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull List<Locale> getCandidateLocales(Locale locale) {
|
/// Get the script of the locale. If the script is empty and the language is Chinese,
|
||||||
return DefaultResourceBundleControl.INSTANCE.getCandidateLocales("", locale);
|
/// the script will be inferred based on the language, the region and the variant.
|
||||||
}
|
public static @NotNull String getScript(Locale locale) {
|
||||||
|
|
||||||
public static String getScript(Locale locale) {
|
|
||||||
if (locale.getScript().isEmpty()) {
|
if (locale.getScript().isEmpty()) {
|
||||||
if (isChinese(locale)) {
|
if (isChinese(locale)) {
|
||||||
if (CHINESE_LATN_VARIANTS.contains(locale.getVariant()))
|
if (CHINESE_LATN_VARIANTS.contains(locale.getVariant()))
|
||||||
@@ -59,6 +69,99 @@ public class LocaleUtils {
|
|||||||
return locale.getScript();
|
return locale.getScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static @NotNull List<Locale> getCandidateLocales(Locale locale) {
|
||||||
|
return DefaultResourceBundleControl.INSTANCE.getCandidateLocales("", locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> @Nullable T getByCandidateLocales(Map<String, T> map, List<Locale> candidateLocales) {
|
||||||
|
for (Locale locale : candidateLocales) {
|
||||||
|
String key = toLanguageKey(locale);
|
||||||
|
if (map.containsKey(key))
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find all localized files in the given directory with the given base name and extension.
|
||||||
|
/// The file name should be in the format of `baseName[_languageTag].ext`.
|
||||||
|
///
|
||||||
|
/// @return A map of language key to file path.
|
||||||
|
public static @NotNull @Unmodifiable Map<String, Path> findAllLocalizedFiles(Path dir, String baseName, String ext) {
|
||||||
|
if (Files.isDirectory(dir)) {
|
||||||
|
String suffix = "." + ext;
|
||||||
|
String defaultName = baseName + suffix;
|
||||||
|
String noDefaultPrefix = baseName + "_";
|
||||||
|
|
||||||
|
try (Stream<Path> list = Files.list(dir)) {
|
||||||
|
var result = new LinkedHashMap<String, Path>();
|
||||||
|
|
||||||
|
list.forEach(file -> {
|
||||||
|
if (Files.isRegularFile(file)) {
|
||||||
|
String fileName = file.getFileName().toString();
|
||||||
|
if (fileName.equals(defaultName)) {
|
||||||
|
result.put(DEFAULT_LANGUAGE_KEY, file);
|
||||||
|
} else if (fileName.startsWith(noDefaultPrefix) && fileName.endsWith(suffix)) {
|
||||||
|
String languageKey = fileName.substring(noDefaultPrefix.length(), fileName.length() - suffix.length())
|
||||||
|
.replace('_', '-');
|
||||||
|
|
||||||
|
if (!languageKey.isEmpty())
|
||||||
|
result.put(languageKey, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warning("Failed to list files in directory " + dir, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Map.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find all localized files in the given directory with the given base name and extensions.
|
||||||
|
/// The file name should be in the format of `baseName[_languageTag].ext`.
|
||||||
|
///
|
||||||
|
/// @return A map of language key to a map of extension to file path.
|
||||||
|
public static @NotNull @Unmodifiable Map<String, Map<String, Path>> findAllLocalizedFiles(Path dir, String baseName, Collection<String> exts) {
|
||||||
|
if (Files.isDirectory(dir)) {
|
||||||
|
try (Stream<Path> list = Files.list(dir)) {
|
||||||
|
var result = new LinkedHashMap<String, Map<String, Path>>();
|
||||||
|
|
||||||
|
list.forEach(file -> {
|
||||||
|
if (Files.isRegularFile(file)) {
|
||||||
|
String fileName = file.getFileName().toString();
|
||||||
|
if (!fileName.startsWith(baseName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
String ext = StringUtils.substringAfterLast(fileName, '.');
|
||||||
|
if (!exts.contains(ext))
|
||||||
|
return;
|
||||||
|
|
||||||
|
String languageKey;
|
||||||
|
int defaultFileNameLength = baseName.length() + ext.length() + 1;
|
||||||
|
if (fileName.length() == defaultFileNameLength)
|
||||||
|
languageKey = DEFAULT_LANGUAGE_KEY;
|
||||||
|
else if (fileName.length() > defaultFileNameLength + 1 && fileName.charAt(baseName.length()) == '_')
|
||||||
|
languageKey = fileName.substring(baseName.length() + 1, fileName.length() - ext.length() - 1)
|
||||||
|
.replace('_', '-');
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
result.computeIfAbsent(languageKey, key -> new HashMap<>())
|
||||||
|
.put(ext, file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warning("Failed to list files in directory " + dir, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Map.of();
|
||||||
|
}
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
public static boolean isEnglish(Locale locale) {
|
public static boolean isEnglish(Locale locale) {
|
||||||
|
|||||||
@@ -17,10 +17,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.i18n;
|
package org.jackhuang.hmcl.util.i18n;
|
||||||
|
|
||||||
|
import com.google.common.jimfs.Configuration;
|
||||||
|
import com.google.common.jimfs.Jimfs;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
@@ -113,4 +120,58 @@ public final class LocaleUtilsTest {
|
|||||||
|
|
||||||
assertEquals("Latn", LocaleUtils.getScript(Locale.forLanguageTag("zh-pinyin")));
|
assertEquals("Latn", LocaleUtils.getScript(Locale.forLanguageTag("zh-pinyin")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindAllLocalizedFiles() throws IOException {
|
||||||
|
try (var testFs = Jimfs.newFileSystem(Configuration.unix())) {
|
||||||
|
Path testDir = testFs.getPath("/test-dir");
|
||||||
|
Files.createDirectories(testDir);
|
||||||
|
|
||||||
|
Files.createFile(testDir.resolve("meow.json"));
|
||||||
|
Files.createFile(testDir.resolve("meow_zh.json"));
|
||||||
|
Files.createFile(testDir.resolve("meow_zh_CN.json"));
|
||||||
|
Files.createFile(testDir.resolve("meow_zh_Hans.json"));
|
||||||
|
Files.createFile(testDir.resolve("meow_zh_Hans_CN.json"));
|
||||||
|
Files.createFile(testDir.resolve("meow_en.json"));
|
||||||
|
Files.createFile(testDir.resolve("meow_en.toml"));
|
||||||
|
|
||||||
|
Files.createFile(testDir.resolve("meow_.json"));
|
||||||
|
Files.createFile(testDir.resolve("meowmeow.json"));
|
||||||
|
Files.createFile(testDir.resolve("woem.json"));
|
||||||
|
Files.createFile(testDir.resolve("meow.txt"));
|
||||||
|
Files.createDirectories(testDir.resolve("subdir"));
|
||||||
|
Files.createDirectories(testDir.resolve("meow_en_US.json"));
|
||||||
|
|
||||||
|
Path notExistsDir = testFs.getPath("/not-exists");
|
||||||
|
Path emptyDir = testFs.getPath("/empty");
|
||||||
|
Files.createDirectories(emptyDir);
|
||||||
|
|
||||||
|
assertEquals(Map.of(), LocaleUtils.findAllLocalizedFiles(emptyDir, "meow", "json"));
|
||||||
|
assertEquals(Map.of(), LocaleUtils.findAllLocalizedFiles(emptyDir, "meow", Set.of("json", "toml")));
|
||||||
|
assertEquals(Map.of(), LocaleUtils.findAllLocalizedFiles(notExistsDir, "meow", "json"));
|
||||||
|
assertEquals(Map.of(), LocaleUtils.findAllLocalizedFiles(notExistsDir, "meow", Set.of("json", "toml")));
|
||||||
|
|
||||||
|
assertEquals(Map.of(
|
||||||
|
"default", testDir.resolve("meow.json"),
|
||||||
|
"zh", testDir.resolve("meow_zh.json"),
|
||||||
|
"zh-CN", testDir.resolve("meow_zh_CN.json"),
|
||||||
|
"zh-Hans", testDir.resolve("meow_zh_Hans.json"),
|
||||||
|
"zh-Hans-CN", testDir.resolve("meow_zh_Hans_CN.json"),
|
||||||
|
"en", testDir.resolve("meow_en.json")
|
||||||
|
),
|
||||||
|
LocaleUtils.findAllLocalizedFiles(testDir, "meow", "json"));
|
||||||
|
assertEquals(Map.of(
|
||||||
|
"default", Map.of("json", testDir.resolve("meow.json")),
|
||||||
|
"zh", Map.of("json", testDir.resolve("meow_zh.json")),
|
||||||
|
"zh-CN", Map.of("json", testDir.resolve("meow_zh_CN.json")),
|
||||||
|
"zh-Hans", Map.of("json", testDir.resolve("meow_zh_Hans.json")),
|
||||||
|
"zh-Hans-CN", Map.of("json", testDir.resolve("meow_zh_Hans_CN.json")),
|
||||||
|
"en", Map.of(
|
||||||
|
"json", testDir.resolve("meow_en.json"),
|
||||||
|
"toml", testDir.resolve("meow_en.toml")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
LocaleUtils.findAllLocalizedFiles(testDir, "meow", Set.of("json", "toml")));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ authlib-injector = "1.2.5"
|
|||||||
|
|
||||||
# testing
|
# testing
|
||||||
junit = "5.13.4"
|
junit = "5.13.4"
|
||||||
|
jimfs = "1.3.0"
|
||||||
|
|
||||||
# plugins
|
# plugins
|
||||||
shadow = "9.0.1"
|
shadow = "9.0.1"
|
||||||
@@ -48,6 +49,7 @@ authlib-injector = { module = "org.glavo.hmcl:authlib-injector", version.ref = "
|
|||||||
|
|
||||||
# testing
|
# testing
|
||||||
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
|
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
|
||||||
|
jimfs = { module = "com.google.jimfs:jimfs", version.ref = "jimfs" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
|
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
|
||||||
|
|||||||
Reference in New Issue
Block a user