Skip to content

Commit cb556ad

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 f49fd5e commit cb556ad

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;
@@ -585,11 +585,7 @@ public static int createAndRunWorkbench(final Display display, final WorkbenchAd
585585
boolean showProgress = PrefUtil.getAPIPreferenceStore()
586586
.getBoolean(IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP);
587587

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

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

19121969
/*

0 commit comments

Comments
 (0)