diff options
author | Dirk Fauth | 2014-09-18 20:47:39 +0000 |
---|---|---|
committer | Dirk Fauth | 2014-09-19 22:01:02 +0000 |
commit | ce9c389022c9affdcda2d97baa44d7216e3a4e2a (patch) | |
tree | 6bc2119546c89518ba09701044ab80c92c273eef /bundles | |
parent | fbf81a373bf16b4c4a24623c0caa9d9d3922b85f (diff) | |
download | rt.equinox.framework-ce9c389022c9affdcda2d97baa44d7216e3a4e2a.tar.gz rt.equinox.framework-ce9c389022c9affdcda2d97baa44d7216e3a4e2a.tar.xz rt.equinox.framework-ce9c389022c9affdcda2d97baa44d7216e3a4e2a.zip |
Bug 444534 - Parsing of nl parameter will now always return a valid
Locale
Change-Id: I24d2deb2ee31aa5fabcbcf87ddd314c765230991
Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com>
Diffstat (limited to 'bundles')
4 files changed, 210 insertions, 27 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/eclipseadaptor/LocaleTransformationTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/eclipseadaptor/LocaleTransformationTest.java new file mode 100644 index 000000000..88a83a14f --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/eclipseadaptor/LocaleTransformationTest.java @@ -0,0 +1,127 @@ +package org.eclipse.osgi.tests.eclipseadaptor; + +import static org.junit.Assert.assertEquals; + +import java.util.Locale; +import org.eclipse.osgi.internal.framework.EquinoxConfiguration; +import org.junit.Test; + +public class LocaleTransformationTest { + + @Test + public void testValidLanguageCountryVariant() { + String localeString = "de_DE_EURO"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("de", locale.getLanguage()); + assertEquals("DE", locale.getCountry()); + assertEquals("EURO", locale.getVariant()); + } + + @Test + public void testValidLanguageCountry() { + String localeString = "de_DE"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("de", locale.getLanguage()); + assertEquals("DE", locale.getCountry()); + assertEquals("", locale.getVariant()); + } + + @Test + public void testValidLanguage() { + String localeString = "de"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("de", locale.getLanguage()); + assertEquals("", locale.getCountry()); + assertEquals("", locale.getVariant()); + } + + @Test + public void testValidCountry() { + String localeString = "_DE"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("", locale.getLanguage()); + assertEquals("DE", locale.getCountry()); + assertEquals("", locale.getVariant()); + } + + @Test + public void testValidLanguageVariant() { + String localeString = "de__EURO"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("de", locale.getLanguage()); + assertEquals("", locale.getCountry()); + assertEquals("EURO", locale.getVariant()); + } + + @Test + public void testValidVariant() { + String localeString = "__EURO"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("", locale.getLanguage()); + assertEquals("", locale.getCountry()); + assertEquals("EURO", locale.getVariant()); + } + + @Test + public void testValidCountryVariant() { + String localeString = "_DE_EURO"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("", locale.getLanguage()); + assertEquals("DE", locale.getCountry()); + assertEquals("EURO", locale.getVariant()); + } + + @Test + public void testInvalidLanguage() { + String localeString = "1234"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("en", locale.getLanguage()); + assertEquals("", locale.getCountry()); + assertEquals("", locale.getVariant()); + } + + @Test + public void testInvalidOneLetterLanguage() { + String localeString = "a"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("en", locale.getLanguage()); + assertEquals("", locale.getCountry()); + assertEquals("", locale.getVariant()); + } + + @Test + public void testThreeLetterValidLanguage() { + String localeString = "kok"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("kok", locale.getLanguage()); + assertEquals("", locale.getCountry()); + assertEquals("", locale.getVariant()); + } + + @Test + public void testInvalidOneLetterCountry() { + String localeString = "_X"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("en", locale.getLanguage()); + assertEquals("", locale.getCountry()); + assertEquals("", locale.getVariant()); + } + + @Test + public void testInvalidThreeLetterCountry() { + String localeString = "_XXX"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("en", locale.getLanguage()); + assertEquals("", locale.getCountry()); + assertEquals("", locale.getVariant()); + } + + @Test + public void testValidNumericAreaCode() { + String localeString = "_029"; + Locale locale = EquinoxConfiguration.toLocale(localeString, Locale.ENGLISH); + assertEquals("", locale.getLanguage()); + assertEquals("029", locale.getCountry()); + assertEquals("", locale.getVariant()); + } +} diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java index 52a4d4a7c..f5642453d 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java @@ -727,33 +727,10 @@ public class EquinoxConfiguration implements EnvironmentInfo { // if the user didn't set the locale with a command line argument then use the default. String nlValue = configuration.getProperty(PROP_OSGI_NL); if (nlValue != null) { - StringTokenizer tokenizer = new StringTokenizer(nlValue, "_"); //$NON-NLS-1$ - int segments = tokenizer.countTokens(); - try { - Locale userLocale = null; - switch (segments) { - case 1 : - // use the 2 arg constructor to maintain compatibility with 1.3.1 - userLocale = new Locale(tokenizer.nextToken(), ""); //$NON-NLS-1$ - break; - case 2 : - userLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken()); - break; - case 3 : - userLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken(), tokenizer.nextToken()); - break; - default : - // if the user passed us in a bogus value then log a message and use the default - System.err.println(NLS.bind(Msg.error_badNL, nlValue)); - userLocale = Locale.getDefault(); - break; - } - Locale.setDefault(userLocale); - // TODO what the heck is this for?? why not just use osgi.nl - configuration.put(PROP_OSGI_NL_USER, nlValue); - } catch (NoSuchElementException e) { - // fall through and use the default - } + Locale userLocale = toLocale(nlValue, Locale.getDefault()); + Locale.setDefault(userLocale); + // TODO what the heck is this for?? why not just use osgi.nl + configuration.put(PROP_OSGI_NL_USER, nlValue); } nlValue = Locale.getDefault().toString(); configuration.put(PROP_OSGI_NL, nlValue); @@ -923,4 +900,79 @@ public class EquinoxConfiguration implements EnvironmentInfo { buf.append(VARIABLE_DELIM_CHAR).append(var); return buf.toString(); } + + /** + * <p> + * Converts a String to a Locale. + * </p> + * + * <p> + * This method takes the string format of a locale and creates the locale object from it. + * </p> + * + * <p> + * This method validates the input strictly. The language code must be lowercase. The country + * code must be uppercase. The separator must be an underscore. The length must be correct. + * </p> + * + * <p> + * This method is inspired by <code>org.apache.commons.lang.LocaleUtils.toLocale(String)</code> + * by fixing the parsing error for uncommon Locales like having a language and a variant code + * but no country code, or a Locale that only consists of a country code. + * </p> + * + * @param str + * the locale String to convert + * @param defaultLocale + * the Locale that should be returned in case of an invalid Locale String + * @return a Locale that matches the specified locale String. If the given input String is + * <code>null</code> or can not be parsed because of an invalid format, the given + * default {@link Locale} will be returned. + */ + public static Locale toLocale(String str, Locale defaultLocale) { + if (str == null) { + System.err.println("Given locale String is null - Default Locale will be used instead."); //$NON-NLS-1$ + return defaultLocale; + } + + String language = ""; //$NON-NLS-1$ + String country = ""; //$NON-NLS-1$ + String variant = ""; //$NON-NLS-1$ + + String[] localeParts = str.split("_"); //$NON-NLS-1$ + if (localeParts.length == 0 || localeParts.length > 3 || (localeParts.length == 1 && localeParts[0].length() == 0)) { + System.err.println(NLS.bind(Msg.error_badNL, str)); + return defaultLocale; + } + + if (localeParts[0].length() > 0 && !localeParts[0].matches("[a-zA-Z]{2,8}")) { //$NON-NLS-1$ + System.err.println(NLS.bind(Msg.error_badNL, str)); + return defaultLocale; + } + + language = localeParts[0]; + + if (localeParts.length > 1) { + if (localeParts[1].length() > 0 && !localeParts[1].matches("[a-zA-Z]{2}|[0-9]{3}")) { //$NON-NLS-1$ + if (language.length() > 0) { + System.err.println(NLS.bind(Msg.error_badNL_language, str)); + return new Locale(language); + } + System.err.println(NLS.bind(Msg.error_badNL, str)); + return defaultLocale; + } + + country = localeParts[1]; + } + + if (localeParts.length == 3) { + if (localeParts[2].length() == 0) { + System.err.println(NLS.bind(Msg.error_badNL_language_country, str)); + return new Locale(language, country); + } + variant = localeParts[2]; + } + + return new Locale(language, country, variant); + } } diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/internal/messages/ExternalMessages.properties b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/internal/messages/ExternalMessages.properties index ab873225a..20a587352 100644 --- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/internal/messages/ExternalMessages.properties +++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/internal/messages/ExternalMessages.properties @@ -75,6 +75,8 @@ ECLIPSE_CANNOT_CHANGE_LOCATION = Cannot change the location once it is set. #NL Problem error_badNL=Bad value: \"{0}\" for NL. Using system default. +error_badNL_language=Bad value: \"{0}\" for NL. Only language part will be used to create the Locale. +error_badNL_language_country=Bad value: \"{0}\" for NL. Only language and country part will be used to create the Locale. #FileMananger messages fileManager_cannotLock = Unable to create lock manager. diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/internal/messages/Msg.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/internal/messages/Msg.java index 01018a7f6..973048ddb 100644 --- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/internal/messages/Msg.java +++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/internal/messages/Msg.java @@ -90,6 +90,8 @@ public class Msg extends NLS { public static String ECLIPSE_STARTUP_APP_ERROR; public static String ECLIPSE_STARTUP_PROPS_NOT_SET; public static String error_badNL; + public static String error_badNL_language; + public static String error_badNL_language_country; public static String location_cannotLock; public static String location_cannotLockNIO; public static String location_folderReadOnly; |