Skip to content

Commit 02780a6

Browse files
committed
Use java.util.Locale in Workbench NL extensions handling
Replaces com.ibm.icu.util.ULocale usage in Workbench with java.util.Locale and drops the matching Import-Package: com.ibm.icu.util from the bundle manifest. The legacy ICU-style locale extension string from Platform.getNLExtensions() and the NL_EXTENSIONS preference (e.g. "@Calendar=hebrew;numbers=arab") is translated to a BCP 47 Unicode locale extension ("-u-ca-hebrew-nu-arab") and applied via Locale.forLanguageTag, so existing preference values keep working for the common keyword names (calendar, collation, currency, numbers, timezone) as well as for two-letter BCP 47 keys. Removes the last com.ibm.icu reference from org.eclipse.ui.workbench.
1 parent 53e3e92 commit 02780a6

2 files changed

Lines changed: 68 additions & 12 deletions

File tree

bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.33.0,4.0.0)",
115115
org.eclipse.emf.ecore.xmi;bundle-version="2.11.0",
116116
org.eclipse.e4.core.di.extensions;bundle-version="0.13.0",
117117
org.eclipse.swt;bundle-version="[3.133.0,4.0.0)"
118-
Import-Package: com.ibm.icu.util,
119-
jakarta.annotation;version="[2.0.0,4.0.0)",
118+
Import-Package: jakarta.annotation;version="[2.0.0,4.0.0)",
120119
jakarta.inject;version="[2.0.0,3.0.0)",
121120
javax.xml.parsers,
122121
org.eclipse.e4.core.commands,

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/Workbench.java

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626

2727
package org.eclipse.ui.internal;
2828

29-
import com.ibm.icu.util.ULocale;
30-
import com.ibm.icu.util.ULocale.Category;
3129
import java.io.BufferedInputStream;
3230
import java.io.File;
3331
import java.io.FileInputStream;
@@ -47,6 +45,8 @@
4745
import java.util.HashSet;
4846
import java.util.Hashtable;
4947
import java.util.List;
48+
import java.util.Locale;
49+
import java.util.Locale.Category;
5050
import java.util.Map;
5151
import java.util.Objects;
5252
import java.util.Set;
@@ -584,11 +584,7 @@ public static int createAndRunWorkbench(final Display display, final WorkbenchAd
584584
boolean showProgress = PrefUtil.getAPIPreferenceStore()
585585
.getBoolean(IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP);
586586

587-
final String nlExtensions = Platform.getNLExtensions();
588-
if (nlExtensions.length() > 0) {
589-
ULocale.setDefault(Category.FORMAT,
590-
new ULocale(ULocale.getDefault(Category.FORMAT).getBaseName() + nlExtensions));
591-
}
587+
applyNlExtensions(Platform.getNLExtensions());
592588

593589
System.setProperty(org.eclipse.e4.ui.workbench.IWorkbench.XMI_URI_ARG,
594590
"org.eclipse.ui.workbench/LegacyIDE.e4xmi"); //$NON-NLS-1$
@@ -1902,10 +1898,71 @@ private void initializeGlobalization() {
19021898
private void initializeNLExtensions() {
19031899
IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
19041900
if (!store.isDefault(IPreferenceConstants.NL_EXTENSIONS)) {
1905-
String nlExtensions = store.getString(IPreferenceConstants.NL_EXTENSIONS);
1906-
ULocale.setDefault(Category.FORMAT,
1907-
new ULocale(ULocale.getDefault(Category.FORMAT).getBaseName() + nlExtensions));
1901+
applyNlExtensions(store.getString(IPreferenceConstants.NL_EXTENSIONS));
1902+
}
1903+
}
1904+
1905+
/**
1906+
* Mapping from ICU-style long keyword names (used in legacy
1907+
* {@code @key=value} locale extension strings) to the corresponding two-letter
1908+
* BCP 47 Unicode locale extension keys.
1909+
*/
1910+
private static final Map<String, String> ICU_TO_BCP47_KEY = Map.ofEntries(
1911+
Map.entry("calendar", "ca"), //$NON-NLS-1$ //$NON-NLS-2$
1912+
Map.entry("collation", "co"), //$NON-NLS-1$ //$NON-NLS-2$
1913+
Map.entry("currency", "cu"), //$NON-NLS-1$ //$NON-NLS-2$
1914+
Map.entry("numbers", "nu"), //$NON-NLS-1$ //$NON-NLS-2$
1915+
Map.entry("timezone", "tz")); //$NON-NLS-1$ //$NON-NLS-2$
1916+
1917+
/**
1918+
* Applies an ICU-style locale extension string (e.g. {@code @calendar=hebrew})
1919+
* to the default {@link Category#FORMAT} locale by translating it to a BCP 47
1920+
* Unicode locale extension and re-parsing the resulting language tag.
1921+
* <p>
1922+
* Supports both ICU long keyword names ({@code calendar}, {@code numbers},
1923+
* ...) and two-letter BCP 47 keys. Underscores in values are normalized to
1924+
* hyphens so legacy compound values such as {@code islamic_civil} are accepted.
1925+
* Unknown keys and ill-formed values are silently dropped, matching the
1926+
* previous best-effort behavior of {@code com.ibm.icu.util.ULocale}.
1927+
* </p>
1928+
* <p>
1929+
* Note: long IANA timezone IDs (e.g. {@code @timezone=America/New_York}) are
1930+
* not translated. BCP 47 Unicode extensions only accept short CLDR timezone
1931+
* identifiers (e.g. {@code @tz=usnyc}), and the JDK does not expose the
1932+
* IANA-to-CLDR mapping. Such values are dropped.
1933+
* </p>
1934+
*/
1935+
private static void applyNlExtensions(String nlExtensions) {
1936+
if (nlExtensions == null || nlExtensions.isEmpty()) {
1937+
return;
1938+
}
1939+
String body = nlExtensions.startsWith("@") ? nlExtensions.substring(1) : nlExtensions; //$NON-NLS-1$
1940+
StringBuilder uExtension = new StringBuilder();
1941+
for (String pair : body.split(";")) { //$NON-NLS-1$
1942+
int eq = pair.indexOf('=');
1943+
if (eq <= 0) {
1944+
continue;
1945+
}
1946+
String rawKey = pair.substring(0, eq).trim().toLowerCase(Locale.ROOT);
1947+
String rawValue = pair.substring(eq + 1).trim().toLowerCase(Locale.ROOT).replace('_', '-');
1948+
if (rawValue.isEmpty()) {
1949+
continue;
1950+
}
1951+
String key = ICU_TO_BCP47_KEY.getOrDefault(rawKey, rawKey.length() == 2 ? rawKey : null);
1952+
if (key == null) {
1953+
continue;
1954+
}
1955+
if (uExtension.length() > 0) {
1956+
uExtension.append('-');
1957+
}
1958+
uExtension.append(key).append('-').append(rawValue);
1959+
}
1960+
if (uExtension.length() == 0) {
1961+
return;
19081962
}
1963+
String baseTag = Locale.getDefault(Category.FORMAT).stripExtensions().toLanguageTag();
1964+
Locale newDefault = Locale.forLanguageTag(baseTag + "-u-" + uExtension); //$NON-NLS-1$
1965+
Locale.setDefault(Category.FORMAT, newDefault);
19091966
}
19101967

19111968
/*

0 commit comments

Comments
 (0)