Skip to content

Commit cab35aa

Browse files
committed
StringUtils.parseLocaleString detects variant without country
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
1 parent d8ee1f5 commit cab35aa

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -781,12 +781,15 @@ public static Locale parseLocale(String localeValue) {
781781

782782
/**
783783
* Parse the given {@code String} representation into a {@link Locale}.
784-
* <p>This is the inverse operation of {@link Locale#toString Locale's toString}.
784+
* <p>For many parsing scenarios, this is an inverse operation of
785+
* {@link Locale#toString Locale's toString}, in a lenient sense.
786+
* This method does not aim for strict {@code Locale} design compliance;
787+
* it is rather specifically tailored for typical Spring parsing needs.
788+
* <p><b>Note: This delegate does not accept the BCP 47 language tag format.
789+
* Please use {@link #parseLocale} for lenient parsing of both formats.</b>
785790
* @param localeString the locale {@code String}: following {@code Locale's}
786791
* {@code toString()} format ("en", "en_UK", etc), also accepting spaces as
787792
* separators (as an alternative to underscores)
788-
* <p>Note: This variant does not accept the BCP 47 language tag format.
789-
* Please use {@link #parseLocale} for lenient parsing of both formats.
790793
* @return a corresponding {@code Locale} instance, or {@code null} if none
791794
* @throws IllegalArgumentException in case of an invalid locale specification
792795
*/
@@ -817,6 +820,12 @@ private static Locale parseLocaleTokens(String localeString, String[] tokens) {
817820
variant = trimLeadingCharacter(variant, '_');
818821
}
819822
}
823+
824+
if ("".equals(variant) && country.startsWith("#")) {
825+
variant = country;
826+
country = "";
827+
}
828+
820829
return (language.length() > 0 ? new Locale(language, country, variant) : null);
821830
}
822831

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,9 +734,35 @@ public void testParseLocaleWithVariantContainingCountryCode() {
734734
assertEquals("Variant containing country code not extracted correctly", variant, locale.getVariant());
735735
}
736736

737-
@Test // SPR-14718
737+
@Test // SPR-14718, SPR-7598
738738
public void testParseJava7Variant() {
739-
assertEquals("sr_#LATN", StringUtils.parseLocaleString("sr_#LATN").toString());
739+
assertEquals("sr__#LATN", StringUtils.parseLocaleString("sr__#LATN").toString());
740+
}
741+
742+
@Test // SPR-16651
743+
public void testAvailableLocalesWithLocaleString() {
744+
for (Locale locale : Locale.getAvailableLocales()) {
745+
Locale parsedLocale = StringUtils.parseLocaleString(locale.toString());
746+
if (parsedLocale == null) {
747+
assertEquals("", locale.getLanguage());
748+
}
749+
else {
750+
assertEquals(parsedLocale.toString(), locale.toString());
751+
}
752+
}
753+
}
754+
755+
@Test // SPR-16651
756+
public void testAvailableLocalesWithLanguageTag() {
757+
for (Locale locale : Locale.getAvailableLocales()) {
758+
Locale parsedLocale = StringUtils.parseLocale(locale.toLanguageTag());
759+
if (parsedLocale == null) {
760+
assertEquals("", locale.getLanguage());
761+
}
762+
else {
763+
assertEquals(parsedLocale.toLanguageTag(), locale.toLanguageTag());
764+
}
765+
}
740766
}
741767

742768
}

0 commit comments

Comments
 (0)