This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 1f4f57dc6f StringUtils improvements
1f4f57dc6f is described below

commit 1f4f57dc6f2b8edc4faa93fb4a5b08cf8f1ca458
Author: James Bognar <[email protected]>
AuthorDate: Sun Nov 30 11:20:54 2025 -0500

    StringUtils improvements
---
 .../org/apache/juneau/bean/openapi3/Items.java     |   6 +-
 .../org/apache/juneau/bean/openapi3/Parameter.java |   6 +-
 .../juneau/bean/openapi3/SecuritySchemeInfo.java   |   6 +-
 .../apache/juneau/common/utils/StringUtils.java    | 129 +++++++++++++++------
 .../juneau/common/utils/StringUtils_Test.java      |   8 +-
 5 files changed, 105 insertions(+), 50 deletions(-)

diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Items.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Items.java
index f857952275..9f3f272b13 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Items.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Items.java
@@ -19,7 +19,7 @@ package org.apache.juneau.bean.openapi3;
 import static org.apache.juneau.common.utils.AssertionUtils.*;
 import static org.apache.juneau.common.utils.CollectionUtils.*;
 import static org.apache.juneau.common.utils.StringUtils.*;
-import static org.apache.juneau.common.utils.StringUtils.containsAny;
+import static org.apache.juneau.common.utils.StringUtils.contains;
 import static org.apache.juneau.common.utils.ThrowableUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
 import static org.apache.juneau.internal.ConverterUtils.*;
@@ -434,7 +434,7 @@ public class Items extends OpenApiElement {
         * @return This object
         */
        public Items setCollectionFormat(String value) {
-               if (isStrict() && ! containsAny(value, 
VALID_COLLECTION_FORMATS))
+               if (isStrict() && ! contains(value, VALID_COLLECTION_FORMATS))
                        throw rex("Invalid value passed in to 
setCollectionFormat(String).  Value=''{0}'', valid values=[{1}]", value, 
toCdl(VALID_COLLECTION_FORMATS));
                collectionFormat = value;
                return this;
@@ -706,7 +706,7 @@ public class Items extends OpenApiElement {
         * @return This object
         */
        public Items setType(String value) {
-               if (isStrict() && ! containsAny(value, VALID_TYPES))
+               if (isStrict() && ! contains(value, VALID_TYPES))
                        throw illegalArg("Invalid value passed in to 
setType(String).  Value=''{0}'', valid values={1}", value, 
Json5Serializer.DEFAULT.toString(VALID_TYPES));
                type = value;
                return this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Parameter.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Parameter.java
index b29125c287..c3c7bc4184 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Parameter.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Parameter.java
@@ -18,7 +18,7 @@ package org.apache.juneau.bean.openapi3;
 
 import static org.apache.juneau.common.utils.AssertionUtils.*;
 import static org.apache.juneau.common.utils.CollectionUtils.*;
-import static org.apache.juneau.common.utils.StringUtils.containsAny;
+import static org.apache.juneau.common.utils.StringUtils.contains;
 import static org.apache.juneau.common.utils.ThrowableUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
 import static org.apache.juneau.internal.ConverterUtils.*;
@@ -357,7 +357,7 @@ public class Parameter extends OpenApiElement {
         * @return This object.
         */
        public Parameter setIn(String value) {
-               if (isStrict() && ! containsAny(value, VALID_IN))
+               if (isStrict() && ! contains(value, VALID_IN))
                        throw rex("Invalid value passed in to setIn(String).  
Value=''{0}'', valid values={1}", value, Json5.of(VALID_IN));
                this.in = value;
                return this;
@@ -403,7 +403,7 @@ public class Parameter extends OpenApiElement {
         * @return This object.
         */
        public Parameter setStyle(String value) {
-               if (isStrict() && ! containsAny(value, VALID_STYLES))
+               if (isStrict() && ! contains(value, VALID_STYLES))
                        throw rex("Invalid value passed in to setStyle(String). 
 Value=''{0}'', valid values={1}", value, Json5.of(VALID_STYLES));
                this.style = value;
                return this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/SecuritySchemeInfo.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/SecuritySchemeInfo.java
index 1a1ec0fe3b..78e153178b 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/SecuritySchemeInfo.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/SecuritySchemeInfo.java
@@ -19,7 +19,7 @@ package org.apache.juneau.bean.openapi3;
 import static org.apache.juneau.common.utils.AssertionUtils.*;
 import static org.apache.juneau.common.utils.CollectionUtils.*;
 import static org.apache.juneau.common.utils.StringUtils.*;
-import static org.apache.juneau.common.utils.StringUtils.containsAny;
+import static org.apache.juneau.common.utils.StringUtils.contains;
 import static org.apache.juneau.common.utils.ThrowableUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
 import static org.apache.juneau.internal.ConverterUtils.*;
@@ -341,7 +341,7 @@ public class SecuritySchemeInfo extends OpenApiElement {
         * @return This object
         */
        public SecuritySchemeInfo setIn(String value) {
-               if (isStrict() && ! containsAny(value, VALID_IN))
+               if (isStrict() && ! contains(value, VALID_IN))
                        throw rex("Invalid value passed in to setIn(String).  
Value=''{0}'', valid values=[{1}]", value, toCdl(VALID_IN));
                in = value;
                return this;
@@ -431,7 +431,7 @@ public class SecuritySchemeInfo extends OpenApiElement {
         * @return This object
         */
        public SecuritySchemeInfo setType(String value) {
-               if (isStrict() && ! containsAny(value, VALID_TYPES))
+               if (isStrict() && ! contains(value, VALID_TYPES))
                        throw rex("Invalid value passed in to setType(String).  
Value=''{0}'', valid values=[{1}]", value, toCdl(VALID_TYPES));
                type = value;
                return this;
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/StringUtils.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/StringUtils.java
index 2b4cf29fdc..e3f5dd903b 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/StringUtils.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/StringUtils.java
@@ -388,13 +388,32 @@ public class StringUtils {
        }
 
        /**
-        * Null-safe {@link String#contains(CharSequence)} operation.
+        * Checks if a string contains any of the specified substrings.
+        *
+        * <p>
+        * This is a null-safe operation that returns <jk>false</jk> if:
+        * <ul>
+        *   <li>The string is <jk>null</jk></li>
+        *   <li>The values array is <jk>null</jk> or empty</li>
+        *   <li>None of the specified substrings are found in the string</li>
+        * </ul>
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      containsAny(<js>"Hello World"</js>, <js>"Hello"</js>, 
<js>"Foo"</js>);   <jc>// true (contains "Hello")</jc>
+        *      containsAny(<js>"Hello World"</js>, <js>"Foo"</js>, 
<js>"Bar"</js>);    <jc>// false</jc>
+        *      containsAny(<jk>null</jk>, <js>"Hello"</js>);                   
         <jc>// false</jc>
+        *      containsAny(<js>"Hello"</js>);                                  
        <jc>// false (no values to check)</jc>
+        * </p>
         *
         * @param s The string to check.
         * @param values The substrings to check for.
         * @return <jk>true</jk> if the string contains any of the specified 
substrings.
+        * @see #contains(String, CharSequence)
+        * @see #contains(String, char...)
+        * @see #notContains(String, String...)
         */
-       public static boolean containsAny(String s, String...values) {
+       public static boolean contains(String s, String...values) {
                if (s == null || values == null || values.length == 0)
                        return false;
                for (var v : values) {
@@ -404,27 +423,6 @@ public class StringUtils {
                return false;
        }
 
-       /**
-        * Returns <jk>true</jk> if the specified string contains any of the 
specified characters.
-        *
-        * @param s The string to test.
-        * @param chars The characters to look for.
-        * @return
-        *      <jk>true</jk> if the specified string contains any of the 
specified characters.
-        *      <br><jk>false</jk> if the string is <jk>null</jk>.
-        */
-       public static boolean containsAny(String s, char...chars) {
-               if (s == null)
-                       return false;
-               for (int i = 0, j = s.length(); i < j; i++) {
-                       var c = s.charAt(i);
-                       for (var c2 : chars)
-                               if (c == c2)
-                                       return true;
-               }
-               return false;
-       }
-
        /**
         * Counts the number of the specified character in the specified string.
         *
@@ -2909,18 +2907,29 @@ public class StringUtils {
        }
 
        /**
-        * Compares two strings for equality, ignoring case.
+        * Tests two strings for case-insensitive equality, but gracefully 
handles nulls.
+        *
+        * <p>
+        * This method handles <jk>null</jk> values gracefully:
+        * <ul>
+        *   <li>Both <jk>null</jk> → returns <jk>true</jk> (same reference 
check)</li>
+        *   <li>One <jk>null</jk> → returns <jk>false</jk></li>
+        *   <li>Neither <jk>null</jk> → compares strings ignoring case</li>
+        * </ul>
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bjava'>
         *      equalsIgnoreCase(<js>"Hello"</js>, <js>"hello"</js>);     
<jc>// true</jc>
         *      equalsIgnoreCase(<js>"Hello"</js>, <js>"WORLD"</js>);     
<jc>// false</jc>
         *      equalsIgnoreCase(<jk>null</jk>, <jk>null</jk>);           
<jc>// true</jc>
+        *      equalsIgnoreCase(<js>"Hello"</js>, <jk>null</jk>);        
<jc>// false</jc>
         * </p>
         *
         * @param str1 The first string.
         * @param str2 The second string.
         * @return <jk>true</jk> if the strings are equal ignoring case, 
<jk>false</jk> otherwise.
+        * @see #equalsIgnoreCase(Object, Object)
+        * @see Utils#eqic(String, String)
         */
        public static boolean equalsIgnoreCase(String str1, String str2) {
                if (str1 == str2)
@@ -4961,7 +4970,7 @@ public class StringUtils {
                if (isEmpty(s))
                        return a();
 
-               if (! containsAny(s, ' ', '\t', '\'', '"'))
+               if (! contains(s, ' ', '\t', '\'', '"'))
                        return a(s);
 
                // S1: Looking for start of token.
@@ -6768,20 +6777,30 @@ public class StringUtils {
        
//------------------------------------------------------------------------------------------------------------------
 
        /**
+        * Null-safe convenience method for {@link String#toLowerCase()}.
+        *
+        * <p>
         * Converts the string to lowercase if not null.
         *
         * @param s The string to convert.
         * @return The lowercase string, or <jk>null</jk> if the input was 
<jk>null</jk>.
+        * @see #upperCase(String)
+        * @see Utils#lc(String)
         */
        public static String lowerCase(String s) {
                return s == null ? null : s.toLowerCase();
        }
 
        /**
+        * Null-safe convenience method for {@link String#toUpperCase()}.
+        *
+        * <p>
         * Converts the string to uppercase if not null.
         *
         * @param s The string to convert.
         * @return The uppercase string, or <jk>null</jk> if the input was 
<jk>null</jk>.
+        * @see #lowerCase(String)
+        * @see Utils#uc(String)
         */
        public static String upperCase(String s) {
                return s == null ? null : s.toUpperCase();
@@ -6790,11 +6809,29 @@ public class StringUtils {
        /**
         * Tests two objects for case-insensitive string equality.
         *
-        * <p>Converts both objects to strings using {@link Object#toString()} 
before comparison.
+        * <p>
+        * Converts both objects to strings using {@link Object#toString()} 
before comparison.
+        * This method handles <jk>null</jk> values gracefully:
+        * <ul>
+        *   <li>Both <jk>null</jk> → returns <jk>true</jk></li>
+        *   <li>One <jk>null</jk> → returns <jk>false</jk></li>
+        *   <li>Neither <jk>null</jk> → compares string representations 
ignoring case</li>
+        * </ul>
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      equalsIgnoreCase(<js>"Hello"</js>, <js>"HELLO"</js>);     
<jc>// true</jc>
+        *      equalsIgnoreCase(<js>"Hello"</js>, <js>"World"</js>);     
<jc>// false</jc>
+        *      equalsIgnoreCase(<jk>null</jk>, <jk>null</jk>);            
<jc>// true</jc>
+        *      equalsIgnoreCase(<js>"Hello"</js>, <jk>null</jk>);         
<jc>// false</jc>
+        *      equalsIgnoreCase(123, <js>"123"</js>);                    
<jc>// true (converts 123 to "123")</jc>
+        * </p>
         *
         * @param a Object 1.
         * @param b Object 2.
         * @return <jk>true</jk> if both objects are equal ignoring case.
+        * @see #equalsIgnoreCase(String, String)
+        * @see Utils#eqic(Object, Object)
         */
        public static boolean equalsIgnoreCase(Object a, Object b) {
                if (a == null && b == null)
@@ -6817,6 +6854,35 @@ public class StringUtils {
                return (vowels.contains(subject.charAt(0)) ? "an " : "a ") + 
subject;
        }
 
+       /**
+        * Returns <jk>true</jk> if the string does not contain any of the 
specified substrings.
+        *
+        * <p>
+        * This is the inverse of {@link #contains(String, String...)}.
+        * Returns <jk>true</jk> if:
+        * <ul>
+        *   <li>The string is <jk>null</jk></li>
+        *   <li>The values array is <jk>null</jk> or empty</li>
+        *   <li>None of the specified substrings are found in the string</li>
+        * </ul>
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      notContains(<js>"Hello World"</js>, <js>"Foo"</js>, 
<js>"Bar"</js>);    <jc>// true</jc>
+        *      notContains(<js>"Hello World"</js>, <js>"Hello"</js>, 
<js>"Foo"</js>);  <jc>// false (contains "Hello")</jc>
+        *      notContains(<jk>null</jk>, <js>"Hello"</js>);                   
         <jc>// true</jc>
+        * </p>
+        *
+        * @param s The string to search.
+        * @param values The values to search for.
+        * @return <jk>true</jk> if the string does not contain any of the 
values.
+        * @see #contains(String, String...)
+        * @see #notContains(String, char...)
+        */
+       public static boolean notContains(String s, String...values) {
+               return ! contains(s, values);
+       }
+
        /**
         * Returns the first non-blank string in the array.
         *
@@ -6861,17 +6927,6 @@ public class StringUtils {
                return joine(toList(values), ',');
        }
 
-       /**
-        * Null-safe not-contains check for multiple string values.
-        *
-        * @param s The string to search.
-        * @param values The values to search for.
-        * @return <jk>true</jk> if the string does not contain any of the 
values.
-        */
-       public static boolean notContains(String s, String...values) {
-               return ! containsAny(s, values);
-       }
-
        /**
         * Converts a comma-delimited string to a set.
         *
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/utils/StringUtils_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/utils/StringUtils_Test.java
index 11c4000bdb..2c3a36453c 100755
--- 
a/juneau-utest/src/test/java/org/apache/juneau/common/utils/StringUtils_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/utils/StringUtils_Test.java
@@ -20,7 +20,7 @@ import static org.apache.juneau.TestUtils.*;
 import static org.apache.juneau.common.utils.CollectionUtils.*;
 import static org.apache.juneau.common.utils.StringUtils.*;
 import static org.apache.juneau.common.utils.StringUtils.compare;
-import static org.apache.juneau.common.utils.StringUtils.containsAny;
+import static org.apache.juneau.common.utils.StringUtils.contains;
 import static org.apache.juneau.common.utils.StringUtils.reverse;
 import static org.apache.juneau.common.utils.Utils.eqic;
 import static org.apache.juneau.junit.bct.BctAssertions.*;
@@ -3234,11 +3234,11 @@ class StringUtils_Test extends TestBase {
                assertTrue(contains("test", "te"));
                assertTrue(contains("test", "st"));
                assertTrue(contains("test", "test"));
-               assertTrue(containsAny("test", "te", "xx"));
+               assertTrue(contains("test", "te", "xx"));
                assertFalse(contains("test", "xx"));
-               assertFalse(containsAny("test", "xx", "yy"));
+               assertFalse(contains("test", "xx", "yy"));
                assertFalse(contains(null, "test"));
-               assertFalse(containsAny("test", (String[])null));
+               assertFalse(contains("test", (String[])null));
        }
 
        @Test

Reply via email to