|
26 | 26 |
|
27 | 27 | package org.eclipse.ui.internal; |
28 | 28 |
|
29 | | -import com.ibm.icu.util.ULocale; |
30 | | -import com.ibm.icu.util.ULocale.Category; |
31 | 29 | import java.io.BufferedInputStream; |
32 | 30 | import java.io.File; |
33 | 31 | import java.io.FileInputStream; |
|
47 | 45 | import java.util.HashSet; |
48 | 46 | import java.util.Hashtable; |
49 | 47 | import java.util.List; |
| 48 | +import java.util.Locale; |
| 49 | +import java.util.Locale.Category; |
50 | 50 | import java.util.Map; |
51 | 51 | import java.util.Objects; |
52 | 52 | import java.util.Set; |
@@ -585,11 +585,7 @@ public static int createAndRunWorkbench(final Display display, final WorkbenchAd |
585 | 585 | boolean showProgress = PrefUtil.getAPIPreferenceStore() |
586 | 586 | .getBoolean(IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP); |
587 | 587 |
|
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()); |
593 | 589 |
|
594 | 590 | System.setProperty(org.eclipse.e4.ui.workbench.IWorkbench.XMI_URI_ARG, |
595 | 591 | "org.eclipse.ui.workbench/LegacyIDE.e4xmi"); //$NON-NLS-1$ |
@@ -1903,10 +1899,71 @@ private void initializeGlobalization() { |
1903 | 1899 | private void initializeNLExtensions() { |
1904 | 1900 | IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore(); |
1905 | 1901 | 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; |
1909 | 1963 | } |
| 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); |
1910 | 1967 | } |
1911 | 1968 |
|
1912 | 1969 | /* |
|
0 commit comments