Introduce StringUtils.truncate()
StringUtils.truncate() serves as central, consistent way for truncating strings used in log messages and exception failure messages, for immediate use in LogFormatUtils and ObjectUtils. See gh-30286 Closes gh-30290
This commit is contained in:
parent
1734deca1e
commit
8161316b1d
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
|
|||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility methods for formatting and logging messages.
|
||||
|
|
@ -78,7 +79,7 @@ public abstract class LogFormatUtils {
|
|||
result = ObjectUtils.nullSafeToString(ex);
|
||||
}
|
||||
if (maxLength != -1) {
|
||||
result = (result.length() > maxLength ? result.substring(0, maxLength) + " (truncated)..." : result);
|
||||
result = StringUtils.truncate(result, maxLength);
|
||||
}
|
||||
if (replaceNewlinesAndControlCharacters) {
|
||||
result = NEWLINE_PATTERN.matcher(result).replaceAll("<EOL>");
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@ public abstract class StringUtils {
|
|||
|
||||
private static final char EXTENSION_SEPARATOR = '.';
|
||||
|
||||
private static final int DEFAULT_TRUNCATION_THRESHOLD = 100;
|
||||
|
||||
private static final String TRUNCATION_SUFFIX = " (truncated)...";
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// General convenience methods for working with Strings
|
||||
|
|
@ -1347,4 +1351,40 @@ public abstract class StringUtils {
|
|||
return arrayToDelimitedString(arr, ",");
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the supplied {@link CharSequence}.
|
||||
* <p>Delegates to {@link #truncate(CharSequence, int)}, supplying {@code 100}
|
||||
* as the threshold.
|
||||
* @param charSequence the {@code CharSequence} to truncate
|
||||
* @return a truncated string, or a string representation of the original
|
||||
* {@code CharSequence} if its length does not exceed the threshold
|
||||
* @since 5.3.27
|
||||
*/
|
||||
public static String truncate(CharSequence charSequence) {
|
||||
return truncate(charSequence, DEFAULT_TRUNCATION_THRESHOLD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the supplied {@link CharSequence}.
|
||||
* <p>If the length of the {@code CharSequence} is greater than the threshold,
|
||||
* this method returns a {@linkplain CharSequence#subSequence(int, int)
|
||||
* subsequence} of the {@code CharSequence} (up to the threshold) appended
|
||||
* with the suffix {@code " (truncated)..."}. Otherwise, this method returns
|
||||
* {@code charSequence.toString()}.
|
||||
* @param charSequence the {@code CharSequence} to truncate
|
||||
* @param threshold the maximum length after which to truncate; must be a
|
||||
* positive number
|
||||
* @return a truncated string, or a string representation of the original
|
||||
* {@code CharSequence} if its length does not exceed the threshold
|
||||
* @since 5.3.27
|
||||
*/
|
||||
public static String truncate(CharSequence charSequence, int threshold) {
|
||||
Assert.isTrue(threshold > 0,
|
||||
() -> "Truncation threshold must be a positive number: " + threshold);
|
||||
if (charSequence.length() > threshold) {
|
||||
return charSequence.subSequence(0, threshold) + TRUNCATION_SUFFIX;
|
||||
}
|
||||
return charSequence.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import java.util.Locale;
|
|||
import java.util.Properties;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
|
@ -757,4 +759,26 @@ class StringUtilsTests {
|
|||
assertThat(StringUtils.collectionToCommaDelimitedString(Collections.singletonList(null))).isEqualTo("null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void truncatePreconditions() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> StringUtils.truncate("foo", 0))
|
||||
.withMessage("Truncation threshold must be a positive number: 0");
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> StringUtils.truncate("foo", -99))
|
||||
.withMessage("Truncation threshold must be a positive number: -99");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource(delimiterString = "-->", textBlock = """
|
||||
aardvark --> aardvark
|
||||
aardvark12 --> aardvark12
|
||||
aardvark123 --> aardvark12 (truncated)...
|
||||
aardvark, bird, cat --> aardvark, (truncated)...
|
||||
"""
|
||||
)
|
||||
void truncate(String text, String truncated) {
|
||||
assertThat(StringUtils.truncate(text, 10)).isEqualTo(truncated);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue