Skip to content

Commit

Permalink
Merge branch 'master' of https://garydgregory@github.com/apache/commo…
Browse files Browse the repository at this point in the history
…ns-lang.git
  • Loading branch information
garydgregory committed Jan 7, 2025
2 parents fc3638e + f5da9b7 commit 4c05091
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 57 deletions.
1 change: 1 addition & 0 deletions src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ The <action> type attribute can be add,update,fix,remove.
<action type="fix" dev="ggregory" due-to="Gary Gregory">Moditect plugin generates split package warnings.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">LocaleUtils.availableLocaleSet() uses predictable iteration order.</action>
<action issue="LANG-1759" type="fix" dev="ggregory" due-to="Maxim Butov, Gary Gregory">SerializationUtils.clone(Object) throws ClassCastException when called with a Serializable lambda.</action>
<action issue="LANG-1759" type="fix" dev="ggregory" due-to="IBue, Gary Gregory, Piotr P. Karwasz">[StringUtils::indexOfAnyBut] redesign due to inconsistent/faulty behavior regarding UTF-16 surrogates #1327.</action>
<!-- ADD -->
<action type="add" dev="ggregory" due-to="Gary Gregory">Add Strings and refactor StringUtils.</action>
<action issue="LANG-1747" type="add" dev="ggregory" due-to="Oliver B. Fischer, Gary Gregory">Add StopWatch.run([Failable]Runnable) and get([Failable]Supplier).</action>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ public static String toString(final Annotation a) {
final ToStringBuilder builder = new ToStringBuilder(a, TO_STRING_STYLE);
for (final Method m : a.annotationType().getDeclaredMethods()) {
if (m.getParameterTypes().length > 0) {
continue; // wtf?
continue; // what?
}
try {
builder.append(m.getName(), m.invoke(a));
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/apache/commons/lang3/RegExUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

/**
* Helpers to process Strings using regular expressions.
*
* @see java.util.regex.Pattern
* @since 3.8
*/
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/org/apache/commons/lang3/StringUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.lang3.function.Suppliers;
import org.apache.commons.lang3.stream.LangCollectors;
Expand Down Expand Up @@ -2853,11 +2855,12 @@ public static int indexOfAnyBut(final CharSequence seq, final CharSequence searc
if (isEmpty(seq) || isEmpty(searchChars)) {
return INDEX_NOT_FOUND;
}
final int[] codePoints = searchChars.codePoints().sorted().toArray();
final Set<Integer> searchSetCodePoints = searchChars.codePoints()
.boxed().collect(Collectors.toSet());
// advance character index from one interpreted codepoint to the next
for (int curSeqCharIdx = 0; curSeqCharIdx < seq.length();) {
final int curSeqCodePoint = Character.codePointAt(seq, curSeqCharIdx);
if (Arrays.binarySearch(codePoints, curSeqCodePoint) < 0) {
if (!searchSetCodePoints.contains(curSeqCodePoint)) {
return curSeqCharIdx;
}
curSeqCharIdx += Character.charCount(curSeqCodePoint); // skip indices to paired low-surrogates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,10 @@ static String[] getStackFrames(final String stackTrace) {
* {@link Throwable} object, decomposing it into a list of
* stack frames.
*
* <p>The result of this method vary by JDK version as this method
* <p>
* The result of this method vary by JDK version as this method
* uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
* On JDK1.3 and earlier, the cause exception will not be shown
* unless the specified throwable alters printStackTrace.</p>
* </p>
*
* @param throwable the {@link Throwable} to examine, may be null
* @return an array of strings describing each stack frame, never null
Expand All @@ -455,12 +455,12 @@ public static String[] getStackFrames(final Throwable throwable) {
}

/**
* Gets the stack trace from a Throwable as a String.
* Gets the stack trace from a Throwable as a String, including suppressed and cause exceptions.
*
* <p>The result of this method vary by JDK version as this method
* <p>
* The result of this method vary by JDK version as this method
* uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
* On JDK1.3 and earlier, the cause exception will not be shown
* unless the specified throwable alters printStackTrace.</p>
* </p>
*
* @param throwable the {@link Throwable} to be examined, may be null
* @return the stack trace as generated by the exception's
Expand Down Expand Up @@ -716,17 +716,19 @@ public static boolean isUnchecked(final Throwable throwable) {
/**
* Prints a compact stack trace for the root cause of a throwable
* to {@code System.err}.
*
* <p>The compact stack trace starts with the root cause and prints
* <p>
* The compact stack trace starts with the root cause and prints
* stack frames up to the place where it was caught and wrapped.
* Then it prints the wrapped exception and continues with stack frames
* until the wrapper exception is caught and wrapped again, etc.</p>
*
* <p>The output of this method is consistent across JDK versions.
* Note that this is the opposite order to the JDK1.4 display.</p>
*
* <p>The method is equivalent to {@code printStackTrace} for throwables
* that don't have nested causes.</p>
* until the wrapper exception is caught and wrapped again, etc.
* </p>
* <p>
* The output of this method is consistent across JDK versions.
* </p>
* <p>
* The method is equivalent to {@code printStackTrace} for throwables
* that don't have nested causes.
* </p>
*
* @param throwable the throwable to output
* @since 2.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,17 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.params.provider.Arguments.arguments;

import java.nio.CharBuffer;
import java.util.Locale;
import java.util.stream.Stream;

import org.hamcrest.core.IsNot;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

/**
* Tests {@link StringUtils} - Equals/IndexOf methods
Expand Down Expand Up @@ -90,6 +95,30 @@ public String toString() {

private static final String[] FOOBAR_SUB_ARRAY = {"ob", "ba"};

static Stream<Arguments> indexOfAnyBut_withSurrogateChars() {
// @formatter:off
return Stream.of(
arguments(CharU20000 + CharU20001, CharU20000, 2),
arguments(CharU20000 + CharU20001, CharU20001, 0),
arguments(CharU20000 + CharU20001, "abcd" + CharUSuppCharLow, 0),
arguments(CharU20000 + CharU20001, "abcd" + CharUSuppCharHigh, 0),
arguments(CharU20000, CharU20000, -1),
arguments(CharU20000, CharU20001, 0),
arguments(CharUSuppCharHigh + "aaaa", CharUSuppCharHigh + "abcd", -1),
arguments(CharUSuppCharHigh + "baaa", CharUSuppCharHigh + "abcd", -1),
arguments(CharUSuppCharHigh + "aaaa", CharU20000 + "abcd", 0),
arguments("aaaa" + CharUSuppCharHigh, CharU20000 + "abcd", 4),
arguments(CharUSuppCharLow + "aaaa", CharU20000 + "abcd", 0),
arguments("aaaa" + CharUSuppCharLow, CharU20000 + "abcd", 4),
arguments(CharU20000 + "aaaa", CharUSuppCharLow + "ab" + CharUSuppCharHigh + "cd", 0),
arguments(CharU20000 + "aaaa", "abcd", 0),
arguments(CharU20000 + "aaaa", "abcd" + CharUSuppCharHigh, 0),
arguments(CharU20000 + "aaaa", "abcd" + CharUSuppCharLow, 0),
arguments("aaaa" + CharU20000, CharU20000 + "abcd", -1)
);
// @formatter:on
}

@Test
public void testCompare_StringString() {
assertEquals(0, StringUtils.compare(null, null));
Expand Down Expand Up @@ -445,25 +474,10 @@ public void testIndexOfAnyBut_StringCharArray() {
assertEquals(0, StringUtils.indexOfAnyBut("aba", 'z'));
}

@Test
public void testIndexOfAnyBut_StringCharArrayWithSurrogateChars() {
assertEquals(2, StringUtils.indexOfAnyBut(CharU20000 + CharU20001, CharU20000.toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + CharU20001, CharU20001.toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + CharU20001, ("abcd" + CharUSuppCharLow).toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + CharU20001, ("abcd" + CharUSuppCharHigh).toCharArray()));
assertEquals(-1, StringUtils.indexOfAnyBut(CharU20000, CharU20000.toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000, CharU20001.toCharArray()));
assertEquals(-1, StringUtils.indexOfAnyBut(CharUSuppCharHigh + "aaaa", (CharUSuppCharHigh + "abcd").toCharArray()));
assertEquals(-1, StringUtils.indexOfAnyBut(CharUSuppCharHigh + "baaa", (CharUSuppCharHigh + "abcd").toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharUSuppCharHigh + "aaaa", (CharU20000 + "abcd").toCharArray()));
assertEquals(4, StringUtils.indexOfAnyBut("aaaa" + CharUSuppCharHigh, (CharU20000 + "abcd").toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharUSuppCharLow + "aaaa", (CharU20000 + "abcd").toCharArray()));
assertEquals(4, StringUtils.indexOfAnyBut("aaaa" + CharUSuppCharLow, (CharU20000 + "abcd").toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + "aaaa", (CharUSuppCharLow + "ab" + CharUSuppCharHigh + "cd").toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + "aaaa", "abcd".toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + "aaaa", ("abcd" + CharUSuppCharHigh).toCharArray()));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + "aaaa", ("abcd" + CharUSuppCharLow).toCharArray()));
assertEquals(-1, StringUtils.indexOfAnyBut("aaaa" + CharU20000, (CharU20000 + "abcd").toCharArray()));
@ParameterizedTest
@MethodSource("indexOfAnyBut_withSurrogateChars")
public void testIndexOfAnyBut_StringCharArrayWithSurrogateChars(final CharSequence seq, final String searchChars, final int expected) {
assertEquals(expected, StringUtils.indexOfAnyBut(seq, searchChars.toCharArray()));
}

@Test
Expand All @@ -483,25 +497,10 @@ public void testIndexOfAnyBut_StringString() {
assertEquals(0, StringUtils.indexOfAnyBut("ab", "z"));
}

@Test
public void testIndexOfAnyBut_StringStringWithSurrogateChars() {
assertEquals(2, StringUtils.indexOfAnyBut(CharU20000 + CharU20001, CharU20000));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + CharU20001, CharU20001));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + CharU20001, "abcd" + CharUSuppCharLow));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + CharU20001, "abcd" + CharUSuppCharHigh));
assertEquals(-1, StringUtils.indexOfAnyBut(CharU20000, CharU20000));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000, CharU20001));
assertEquals(-1, StringUtils.indexOfAnyBut(CharUSuppCharHigh + "aaaa", CharUSuppCharHigh + "abcd"));
assertEquals(-1, StringUtils.indexOfAnyBut(CharUSuppCharHigh + "baaa", CharUSuppCharHigh + "abcd"));
assertEquals(0, StringUtils.indexOfAnyBut(CharUSuppCharHigh + "aaaa", CharU20000 + "abcd"));
assertEquals(4, StringUtils.indexOfAnyBut("aaaa" + CharUSuppCharHigh, CharU20000 + "abcd"));
assertEquals(0, StringUtils.indexOfAnyBut(CharUSuppCharLow + "aaaa", CharU20000 + "abcd"));
assertEquals(4, StringUtils.indexOfAnyBut("aaaa" + CharUSuppCharLow, CharU20000 + "abcd"));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + "aaaa", CharUSuppCharLow + "ab" + CharUSuppCharHigh + "cd"));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + "aaaa", "abcd"));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + "aaaa", "abcd" + CharUSuppCharHigh));
assertEquals(0, StringUtils.indexOfAnyBut(CharU20000 + "aaaa", "abcd" + CharUSuppCharLow));
assertEquals(-1, StringUtils.indexOfAnyBut("aaaa" + CharU20000, CharU20000 + "abcd"));
@ParameterizedTest
@MethodSource("indexOfAnyBut_withSurrogateChars")
public void testIndexOfAnyBut_StringStringWithSurrogateChars(final CharSequence seq, final CharSequence searchChars, final int expected) {
assertEquals(expected, StringUtils.indexOfAnyBut(seq, searchChars));
}

@Test
Expand Down

0 comments on commit 4c05091

Please sign in to comment.