From 35fb9fca83af4ffbaf6f1163a927d8751938fda3 Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Sat, 5 Mar 2022 19:21:25 -0500 Subject: [PATCH 1/4] LANG-1172: Support dash as a delimiter in locales (#766) * LANG-1172: Support dash as a delimiter in locales * Extract constants for dash and underscore * Prioritize old delimiter in comparison order --- .../java/org/apache/commons/lang3/LocaleUtils.java | 13 +++++++++---- .../org/apache/commons/lang3/LocaleUtilsTest.java | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/apache/commons/lang3/LocaleUtils.java b/src/main/java/org/apache/commons/lang3/LocaleUtils.java index 587d3a7e9..69f5eae95 100644 --- a/src/main/java/org/apache/commons/lang3/LocaleUtils.java +++ b/src/main/java/org/apache/commons/lang3/LocaleUtils.java @@ -36,6 +36,8 @@ import java.util.concurrent.ConcurrentMap; * @since 2.2 */ public class LocaleUtils { + private static final char UNDERSCORE = '_'; + private static final char DASH = '-'; // class to avoid synchronization (Init on demand) static class SyncAvoid { @@ -248,7 +250,9 @@ public class LocaleUtils { return new Locale(str); } - final String[] segments = str.split("_", -1); + final String[] segments = str.indexOf(UNDERSCORE) != -1 + ? str.split(String.valueOf(UNDERSCORE), -1) + : str.split(String.valueOf(DASH), -1); final String language = segments[0]; if (segments.length == 2) { final String country = segments[1]; @@ -289,6 +293,7 @@ public class LocaleUtils { * LocaleUtils.toLocale("") = new Locale("", "") * LocaleUtils.toLocale("en") = new Locale("en", "") * LocaleUtils.toLocale("en_GB") = new Locale("en", "GB") + * LocaleUtils.toLocale("en-GB") = new Locale("en", "GB") * LocaleUtils.toLocale("en_001") = new Locale("en", "001") * LocaleUtils.toLocale("en_GB_xxx") = new Locale("en", "GB", "xxx") (#) * @@ -300,7 +305,7 @@ public class LocaleUtils { *

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 separator must be an underscore or a dash. * The length must be correct. *

* @@ -325,7 +330,7 @@ public class LocaleUtils { throw new IllegalArgumentException("Invalid locale format: " + str); } final char ch0 = str.charAt(0); - if (ch0 == '_') { + if (ch0 == UNDERSCORE || ch0 == DASH) { if (len < 3) { throw new IllegalArgumentException("Invalid locale format: " + str); } @@ -340,7 +345,7 @@ public class LocaleUtils { if (len < 5) { throw new IllegalArgumentException("Invalid locale format: " + str); } - if (str.charAt(3) != '_') { + if (str.charAt(3) != ch0) { throw new IllegalArgumentException("Invalid locale format: " + str); } return new Locale(StringUtils.EMPTY, str.substring(1, 3), str.substring(4)); diff --git a/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java b/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java index d8bd84dd1..112f5baec 100644 --- a/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java @@ -170,11 +170,10 @@ public class LocaleUtilsTest { @Test public void testToLocale_2Part() { assertValidToLocale("us_EN", "us", "EN"); + assertValidToLocale("us-EN", "us", "EN"); //valid though doesn't exist assertValidToLocale("us_ZH", "us", "ZH"); - assertThrows( - IllegalArgumentException.class, () -> LocaleUtils.toLocale("us-EN"), "Should fail as not underscore"); assertThrows( IllegalArgumentException.class, () -> LocaleUtils.toLocale("us_En"), @@ -203,6 +202,7 @@ public class LocaleUtilsTest { @Test public void testToLocale_3Part() { assertValidToLocale("us_EN_A", "us", "EN", "A"); + assertValidToLocale("us-EN-A", "us", "EN", "A"); // this isn't pretty, but was caused by a jdk bug it seems // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4210525 if (SystemUtils.isJavaVersionAtLeast(JAVA_1_4)) { @@ -214,7 +214,7 @@ public class LocaleUtilsTest { } assertThrows( - IllegalArgumentException.class, () -> LocaleUtils.toLocale("us_EN-a"), "Should fail as not underscore"); + IllegalArgumentException.class, () -> LocaleUtils.toLocale("us_EN-a"), "Should fail as no consistent delimiter"); assertThrows( IllegalArgumentException.class, () -> LocaleUtils.toLocale("uu_UU_"), "Must be 3, 5 or 7+ in length"); } From cd29ff77783bb870dae96c2e2880a7bbbc9e61d5 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 5 Mar 2022 19:25:04 -0500 Subject: [PATCH 2/4] LANG-1172: Support dash as a delimiter in locales #766 --- src/changes/changes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 6b89e5f03..42b6a6dfd 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -68,7 +68,7 @@ The type attribute can be add,update,fix,remove. Fix NullPointerException in ThreadUtils.getSystemThreadGroup() when the current thread is stopped. ArrayUtils.toPrimitive(Boolean...) null array elements map to false, like Boolean.parseBoolean(null) and its callers return false. StrBuilder.StrBuilderReader.skip(long): Throw an exception when an implicit narrowing conversion in a compound assignment would result in information loss or a numeric error such as an overflows. - + Support dash as a delimiter in locales #766. Add EnumUtils.getEnumSystemProperty(...). Add TriConsumer. From ccc12ff185f3cdd92c65c90e1cf573f5f3fecaf0 Mon Sep 17 00:00:00 2001 From: Maria Buiakova <67376962+mbuiakova@users.noreply.github.com> Date: Sun, 6 Mar 2022 17:14:06 +0100 Subject: [PATCH 3/4] LANG-1668 Update getMatchingMethod documentation. (#862) Adds a mention of IllegalStateException in case no unique method is found. --- src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java b/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java index eff0ee874..b086609ff 100644 --- a/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java +++ b/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java @@ -730,6 +730,7 @@ public class MethodUtils { * @param cls The class that will be subjected to the method search * @param methodName The method that we wish to call * @param parameterTypes Argument class types + * @throws IllegalStateException if there is no unique result * @return The method * * @since 3.5 From 5aa058c9d1d57547200b9f90285278fa1914e372 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 6 Mar 2022 11:16:27 -0500 Subject: [PATCH 4/4] [LANG-1668] Update getMatchingMethod documentation. #862. --- src/changes/changes.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 42b6a6dfd..076d597e8 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -69,6 +69,7 @@ The type attribute can be add,update,fix,remove. ArrayUtils.toPrimitive(Boolean...) null array elements map to false, like Boolean.parseBoolean(null) and its callers return false. StrBuilder.StrBuilderReader.skip(long): Throw an exception when an implicit narrowing conversion in a compound assignment would result in information loss or a numeric error such as an overflows. Support dash as a delimiter in locales #766. + Update getMatchingMethod documentation. #862. Add EnumUtils.getEnumSystemProperty(...). Add TriConsumer.