-
Notifications
You must be signed in to change notification settings - Fork 0
Use java.util.Locale in Workbench NL extensions handling #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -26,8 +26,6 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package org.eclipse.ui.internal; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.ibm.icu.util.ULocale; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.ibm.icu.util.ULocale.Category; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.io.BufferedInputStream; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.io.File; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.io.FileInputStream; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -47,6 +45,8 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.HashSet; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Hashtable; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Locale; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Locale.Category; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Map; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Objects; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Set; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -584,11 +584,7 @@ public static int createAndRunWorkbench(final Display display, final WorkbenchAd | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| boolean showProgress = PrefUtil.getAPIPreferenceStore() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .getBoolean(IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final String nlExtensions = Platform.getNLExtensions(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (nlExtensions.length() > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ULocale.setDefault(Category.FORMAT, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new ULocale(ULocale.getDefault(Category.FORMAT).getBaseName() + nlExtensions)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| applyNlExtensions(Platform.getNLExtensions()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| System.setProperty(org.eclipse.e4.ui.workbench.IWorkbench.XMI_URI_ARG, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "org.eclipse.ui.workbench/LegacyIDE.e4xmi"); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1902,10 +1898,71 @@ private void initializeGlobalization() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private void initializeNLExtensions() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!store.isDefault(IPreferenceConstants.NL_EXTENSIONS)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String nlExtensions = store.getString(IPreferenceConstants.NL_EXTENSIONS); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ULocale.setDefault(Category.FORMAT, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new ULocale(ULocale.getDefault(Category.FORMAT).getBaseName() + nlExtensions)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| applyNlExtensions(store.getString(IPreferenceConstants.NL_EXTENSIONS)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Mapping from ICU-style long keyword names (used in legacy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * {@code @key=value} locale extension strings) to the corresponding two-letter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * BCP 47 Unicode locale extension keys. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static final Map<String, String> ICU_TO_BCP47_KEY = Map.ofEntries( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Map.entry("calendar", "ca"), //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Map.entry("collation", "co"), //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Map.entry("currency", "cu"), //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Map.entry("numbers", "nu"), //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Map.entry("timezone", "tz")); //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Applies an ICU-style locale extension string (e.g. {@code @calendar=hebrew}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * to the default {@link Category#FORMAT} locale by translating it to a BCP 47 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Unicode locale extension and re-parsing the resulting language tag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * <p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Supports both ICU long keyword names ({@code calendar}, {@code numbers}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * ...) and two-letter BCP 47 keys. Underscores in values are normalized to | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * hyphens so legacy compound values such as {@code islamic_civil} are accepted. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Unknown keys and ill-formed values are silently dropped, matching the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * previous best-effort behavior of {@code com.ibm.icu.util.ULocale}. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * </p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * <p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Note: long IANA timezone IDs (e.g. {@code @timezone=America/New_York}) are | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * not translated. BCP 47 Unicode extensions only accept short CLDR timezone | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * identifiers (e.g. {@code @tz=usnyc}), and the JDK does not expose the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * IANA-to-CLDR mapping. Such values are dropped. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * </p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static void applyNlExtensions(String nlExtensions) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (nlExtensions == null || nlExtensions.isEmpty()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String body = nlExtensions.startsWith("@") ? nlExtensions.substring(1) : nlExtensions; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| StringBuilder uExtension = new StringBuilder(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (String pair : body.split(";")) { //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int eq = pair.indexOf('='); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (eq <= 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String rawKey = pair.substring(0, eq).trim().toLowerCase(Locale.ROOT); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String rawValue = pair.substring(eq + 1).trim().toLowerCase(Locale.ROOT).replace('_', '-'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (rawValue.isEmpty()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String key = ICU_TO_BCP47_KEY.getOrDefault(rawKey, rawKey.length() == 2 ? rawKey : null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (key == null) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (uExtension.length() > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uExtension.append('-'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uExtension.append(key).append('-').append(rawValue); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1941
to
+1959
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current parsing logic assumes that the ICU keywords often used underscores (e.g., Consider replacing underscores with hyphens in the
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (uExtension.length() == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String baseTag = Locale.getDefault(Category.FORMAT).stripExtensions().toLanguageTag(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Locale newDefault = Locale.forLanguageTag(baseTag + "-u-" + uExtension); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Locale.setDefault(Category.FORMAT, newDefault); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mapping of
timezoneto the BCP 47 keytzmay result in a loss of functionality for many existing configurations.Legacy ICU-style locale extensions often use long IANA timezone IDs (e.g.,
@timezone=America/New_York). However, BCP 47 Unicode locale extensions (the-u-section used byjava.util.Locale) strictly require short CLDR identifiers (e.g.,usnycforAmerica/New_York).Since
Locale.forLanguageTagis used here for a best-effort approach, values containing slashes or exceeding the 8-character subtag limit will be considered ill-formed and likely ignored by the JVM. This is a regression compared to the previousULocaleimplementation which could resolve long IDs. If maintaining support for long timezone IDs is required, a manual mapping or a lookup viajava.time.ZoneIdmight be necessary to find the corresponding BCP 47 short ID.