Browse Source

StringUtils.parseLocaleString detects variant without country

The parseLocale method also turns an empty locale into null now, compatible with parseLocaleString behavior.

Includes tests for parsing all available locales on the JVM, checking toString/toLanguageTag equality between parsed and original locale.

Issue: SPR-7598
Issue: SPR-16651

(cherry picked from commit cab35aa)
pull/1916/head
Juergen Hoeller 6 years ago
parent
commit
55563c16b5
  1. 18
      spring-core/src/main/java/org/springframework/util/StringUtils.java
  2. 30
      spring-core/src/test/java/org/springframework/util/StringUtilsTests.java

18
spring-core/src/main/java/org/springframework/util/StringUtils.java

@ -772,19 +772,23 @@ public abstract class StringUtils { @@ -772,19 +772,23 @@ public abstract class StringUtils {
public static Locale parseLocale(String localeValue) {
String[] tokens = tokenizeLocaleSource(localeValue);
if (tokens.length == 1) {
return Locale.forLanguageTag(localeValue);
Locale resolved = Locale.forLanguageTag(localeValue);
return (resolved.getLanguage().length() > 0 ? resolved : null);
}
return parseLocaleTokens(localeValue, tokens);
}
/**
* Parse the given {@code String} representation into a {@link Locale}.
* <p>This is the inverse operation of {@link Locale#toString Locale's toString}.
* <p>For many parsing scenarios, this is an inverse operation of
* {@link Locale#toString Locale's toString}, in a lenient sense.
* This method does not aim for strict {@code Locale} design compliance;
* it is rather specifically tailored for typical Spring parsing needs.
* <p><b>Note: This delegate does not accept the BCP 47 language tag format.
* Please use {@link #parseLocale} for lenient parsing of both formats.</b>
* @param localeString the locale {@code String}: following {@code Locale's}
* {@code toString()} format ("en", "en_UK", etc), also accepting spaces as
* separators (as an alternative to underscores)
* <p>Note: This variant does not accept the BCP 47 language tag format.
* Please use {@link #parseLocale} for lenient parsing of both formats.
* @return a corresponding {@code Locale} instance, or {@code null} if none
* @throws IllegalArgumentException in case of an invalid locale specification
*/
@ -815,6 +819,12 @@ public abstract class StringUtils { @@ -815,6 +819,12 @@ public abstract class StringUtils {
variant = trimLeadingCharacter(variant, '_');
}
}
if ("".equals(variant) && country.startsWith("#")) {
variant = country;
country = "";
}
return (language.length() > 0 ? new Locale(language, country, variant) : null);
}

30
spring-core/src/test/java/org/springframework/util/StringUtilsTests.java

@ -734,9 +734,35 @@ public class StringUtilsTests { @@ -734,9 +734,35 @@ public class StringUtilsTests {
assertEquals("Variant containing country code not extracted correctly", variant, locale.getVariant());
}
@Test // SPR-14718
@Test // SPR-14718, SPR-7598
public void testParseJava7Variant() {
assertEquals("sr_#LATN", StringUtils.parseLocaleString("sr_#LATN").toString());
assertEquals("sr__#LATN", StringUtils.parseLocaleString("sr__#LATN").toString());
}
@Test // SPR-16651
public void testAvailableLocalesWithLocaleString() {
for (Locale locale : Locale.getAvailableLocales()) {
Locale parsedLocale = StringUtils.parseLocaleString(locale.toString());
if (parsedLocale == null) {
assertEquals("", locale.getLanguage());
}
else {
assertEquals(parsedLocale.toString(), locale.toString());
}
}
}
@Test // SPR-16651
public void testAvailableLocalesWithLanguageTag() {
for (Locale locale : Locale.getAvailableLocales()) {
Locale parsedLocale = StringUtils.parseLocale(locale.toLanguageTag());
if (parsedLocale == null) {
assertEquals("", locale.getLanguage());
}
else {
assertEquals(parsedLocale.toLanguageTag(), locale.toLanguageTag());
}
}
}
}

Loading…
Cancel
Save