优化对于 ISO 639-3 语言代码的支持 (#4455)
This commit is contained in:
@@ -31,8 +31,8 @@ import java.util.ResourceBundle;
|
||||
/// - For all Chinese locales, `zh-CN` is always added to the candidate list. If `zh-Hans` already exists in the candidate list,
|
||||
/// `zh-CN` is inserted before `zh`; otherwise, it is inserted after `zh`.
|
||||
/// - For all Traditional Chinese locales, `zh-TW` is always added to the candidate list (before `zh`).
|
||||
/// - For all Chinese variants (such as `lzh`, `cmn`, `yue`, etc.), a candidate list with the language code replaced by `zh`
|
||||
/// is added to the end of the candidate list.
|
||||
/// - For all [supported][LocaleUtils#toISO1Language(String)] ISO 639-3 language code (such as `eng`, `zho`, `lzh`, etc.),
|
||||
/// a candidate list with the language code replaced by the ISO 639-1 (Macro)language code is added to the end of the candidate list.
|
||||
///
|
||||
/// @author Glavo
|
||||
public class DefaultResourceBundleControl extends ResourceBundle.Control {
|
||||
@@ -52,53 +52,57 @@ public class DefaultResourceBundleControl extends ResourceBundle.Control {
|
||||
public List<Locale> getCandidateLocales(String baseName, Locale locale) {
|
||||
if (locale.getLanguage().isEmpty())
|
||||
return getCandidateLocales(baseName, Locale.ENGLISH);
|
||||
|
||||
if (LocaleUtils.isChinese(locale)) {
|
||||
String language = locale.getLanguage();
|
||||
else if (LocaleUtils.isChinese(locale)) {
|
||||
String script = locale.getScript();
|
||||
|
||||
if (script.isEmpty()) {
|
||||
script = LocaleUtils.getScript(locale);
|
||||
locale = new Locale.Builder()
|
||||
.setLocale(locale)
|
||||
.setScript(script)
|
||||
.build();
|
||||
if (!script.isEmpty())
|
||||
return getCandidateLocales(baseName, new Locale.Builder()
|
||||
.setLocale(locale)
|
||||
.setScript(script)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
List<Locale> locales = super.getCandidateLocales("", locale);
|
||||
String language = locale.getLanguage();
|
||||
|
||||
if (language.equals("zh")) {
|
||||
if (locales.contains(LocaleUtils.LOCALE_ZH_HANT) && !locales.contains(Locale.TRADITIONAL_CHINESE)) {
|
||||
locales = ensureEditable(locales);
|
||||
int chineseIdx = locales.indexOf(Locale.CHINESE);
|
||||
if (chineseIdx >= 0)
|
||||
locales.add(chineseIdx, Locale.TRADITIONAL_CHINESE);
|
||||
}
|
||||
List<Locale> locales = super.getCandidateLocales(baseName, locale);
|
||||
|
||||
if (!locales.contains(Locale.SIMPLIFIED_CHINESE)) {
|
||||
int chineseIdx = locales.indexOf(Locale.CHINESE);
|
||||
// Is ISO 639-3 language tag
|
||||
if (language.length() == 3) {
|
||||
String iso1 = LocaleUtils.toISO1Language(locale.getLanguage());
|
||||
|
||||
if (chineseIdx >= 0) {
|
||||
locales = ensureEditable(locales);
|
||||
if (locales.contains(LocaleUtils.LOCALE_ZH_HANS))
|
||||
locales.add(chineseIdx, Locale.SIMPLIFIED_CHINESE);
|
||||
else
|
||||
locales.add(chineseIdx + 1, Locale.SIMPLIFIED_CHINESE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (iso1.length() == 2) {
|
||||
locales = ensureEditable(locales);
|
||||
locales.removeIf(it -> !it.getLanguage().equals(language));
|
||||
|
||||
locales.addAll(getCandidateLocales("", new Locale.Builder()
|
||||
locales.addAll(getCandidateLocales(baseName, new Locale.Builder()
|
||||
.setLocale(locale)
|
||||
.setLanguage("zh")
|
||||
.setLanguage(iso1)
|
||||
.build()));
|
||||
}
|
||||
} else if (language.equals("zh")) {
|
||||
if (locales.contains(LocaleUtils.LOCALE_ZH_HANT) && !locales.contains(Locale.TRADITIONAL_CHINESE)) {
|
||||
locales = ensureEditable(locales);
|
||||
int chineseIdx = locales.indexOf(Locale.CHINESE);
|
||||
if (chineseIdx >= 0)
|
||||
locales.add(chineseIdx, Locale.TRADITIONAL_CHINESE);
|
||||
}
|
||||
|
||||
return locales;
|
||||
if (!locales.contains(Locale.SIMPLIFIED_CHINESE)) {
|
||||
int chineseIdx = locales.indexOf(Locale.CHINESE);
|
||||
|
||||
if (chineseIdx >= 0) {
|
||||
locales = ensureEditable(locales);
|
||||
if (locales.contains(LocaleUtils.LOCALE_ZH_HANS))
|
||||
locales.add(chineseIdx, Locale.SIMPLIFIED_CHINESE);
|
||||
else
|
||||
locales.add(chineseIdx + 1, Locale.SIMPLIFIED_CHINESE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.getCandidateLocales(baseName, locale);
|
||||
return locales;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,20 @@ public final class LocaleUtils {
|
||||
: locale.stripExtensions().toLanguageTag();
|
||||
}
|
||||
|
||||
public static boolean isISO1Language(String language) {
|
||||
return language.length() == 2;
|
||||
}
|
||||
|
||||
public static boolean isISO3Language(String language) {
|
||||
return language.length() == 3;
|
||||
}
|
||||
|
||||
public static @NotNull String getISO1Language(Locale locale) {
|
||||
String language = locale.getLanguage();
|
||||
if (language.isEmpty()) return "en";
|
||||
return isISO3Language(language) ? toISO1Language(language) : language;
|
||||
}
|
||||
|
||||
/// Get the script of the locale. If the script is empty and the language is Chinese,
|
||||
/// the script will be inferred based on the language, the region and the variant.
|
||||
public static @NotNull String getScript(Locale locale) {
|
||||
@@ -164,20 +178,29 @@ public final class LocaleUtils {
|
||||
|
||||
// ---
|
||||
|
||||
/// Try to convert ISO 639-3 language codes to ISO 639-1 language codes.
|
||||
public static String toISO1Language(String languageTag) {
|
||||
return switch (languageTag) {
|
||||
case "eng" -> "en";
|
||||
case "spa" -> "es";
|
||||
case "jpa" -> "ja";
|
||||
case "rus" -> "ru";
|
||||
case "ukr" -> "uk";
|
||||
case "zho", "cmn", "lzh", "cdo", "cjy", "cpx", "czh",
|
||||
"gan", "hak", "hsn", "mnp", "nan", "wuu", "yue" -> "zh";
|
||||
default -> languageTag;
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean isEnglish(Locale locale) {
|
||||
return locale.getLanguage().equals("en") || locale.getLanguage().isEmpty();
|
||||
return "en".equals(getISO1Language(locale));
|
||||
}
|
||||
|
||||
public static final Set<String> CHINESE_TRADITIONAL_REGIONS = Set.of("TW", "HK", "MO");
|
||||
public static final Set<String> CHINESE_LATN_VARIANTS = Set.of("pinyin", "wadegile", "tongyong");
|
||||
public static final Set<String> CHINESE_LANGUAGES = Set.of(
|
||||
"zh",
|
||||
"zho", "cmn", "lzh", "cdo", "cjy", "cpx", "czh",
|
||||
"gan", "hak", "hsn", "mnp", "nan", "wuu", "yue"
|
||||
);
|
||||
|
||||
public static boolean isChinese(Locale locale) {
|
||||
return CHINESE_LANGUAGES.contains(locale.getLanguage());
|
||||
return "zh".equals(getISO1Language(locale));
|
||||
}
|
||||
|
||||
private LocaleUtils() {
|
||||
|
||||
Reference in New Issue
Block a user