Skip to content

Commit

Permalink
Merge pull request #528 from scireum/feature/mko/SIRI-960-5
Browse files Browse the repository at this point in the history
Introduces `truncateMiddle` which is capable of truncating a string in the middle
  • Loading branch information
mko-sci authored May 23, 2024
2 parents 8f606fe + 7c2ff38 commit 8faf6b9
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 5 deletions.
54 changes: 49 additions & 5 deletions src/main/java/sirius/kernel/commons/Strings.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@
*/
public class Strings {

/**
* Contains the characters which should be used in order to depict an ellipsis.
*/
private static final String ELLIPSIS = "…";

/**
* Contains the marker/signal which should be used to depict that the string has been truncated.
*/
private static final String TRUNCATED_SIGNAL = ELLIPSIS + "[" + ELLIPSIS + "]" + ELLIPSIS;

/**
* Contains all characters which can safely be used for codes without too much confusion (e.g. 0 vs O are
* excluded).
Expand Down Expand Up @@ -378,20 +388,54 @@ public static String limit(@Nullable Object input, int length) {
* @param length the max. number of characters to return. Note: If the parameter is less than 1 an empty string is returned.
* @param showEllipsis whether to append three dots if <tt>input</tt> is longer than <tt>length</tt>
* @return a part of the string representation of the given <tt>input</tt>. If input is shorter
* than <tt>length</tt>, the full value is returned. If input is <tt>null</tt> or empty, "" is returned. This also applies if <tt>length</tt> is less than 1.
* than <tt>length</tt>, the trimmed input value is returned. If input is <tt>null</tt> or empty, "" is returned. This also applies if <tt>length</tt> is less than 1.
*/
public static String limit(@Nullable Object input, int length, boolean showEllipsis) {
if (isEmpty(input) || length <= 0) {
return "";
}
String str = String.valueOf(input).trim();
if (str.length() > length) {
return str.substring(0, (showEllipsis ? length - 1 : length)) + (showEllipsis ? "…" : "");
String trimmedInputString = String.valueOf(input).trim();
if (trimmedInputString.length() > length) {
return trimmedInputString.substring(0, (showEllipsis ? length - ELLIPSIS.length() : length))
+ (showEllipsis ? ELLIPSIS : "");
} else {
return str;
return trimmedInputString;
}
}

/**
* Truncates the given input in the middle by preserving characters from the start and end.
* <p>
* Note:
* Adds a truncated signal in the form of "…[…]…" in the middle of the string. This signal consist of 5 chars.
* The chars of the signal are considered when determining if a truncation is necessary. Therefore, a truncation only
* takes place if the input string is longer than <tt>charsToPreserveFromStart</tt> + <tt>charsToPreserveFromEnd</tt> + length of the truncated signal.
*
* @param input the input to truncate
* @param charsToPreserveFromStart the number of characters to preserve from the start. Note that this value must be greater than or equal to 0.
* @param charsToPreserveFromEnd the number of characters to preserve from the end. Note that this value must be greater than or equal to 0.
* @return a part of the string representation of the given <tt>input</tt> with a truncated signal added in the middle.
* If input is shorter than or equal to (<tt>charsToPreserveFromStart</tt> + <tt>charsToPreserveFromEnd</tt> + length of the truncated signal), the trimmed input value is returned.
* If input is <tt>null</tt> or empty, "" is returned. This also applies if (<tt>charsToPreserveFromStart</tt> + <tt>charsToPreserveFromEnd</tt>) is 0.
*/
public static String truncateMiddle(@Nullable Object input,
int charsToPreserveFromStart,
int charsToPreserveFromEnd) {
int charsToPreserve = charsToPreserveFromStart + charsToPreserveFromEnd;
if (isEmpty(input) || charsToPreserveFromStart < 0 || charsToPreserveFromEnd < 0 || charsToPreserve == 0) {
return "";
}

String trimmedInputString = String.valueOf(input).trim();
if (trimmedInputString.length() <= charsToPreserve + TRUNCATED_SIGNAL.length()) {
return trimmedInputString;
}

String start = trimmedInputString.substring(0, charsToPreserveFromStart).trim();
String end = trimmedInputString.substring(trimmedInputString.length() - charsToPreserveFromEnd).trim();
return start + TRUNCATED_SIGNAL + end;
}

/**
* Returns a string representation of the given map.
* <p>
Expand Down
26 changes: 26 additions & 0 deletions src/test/kotlin/sirius/kernel/commons/StringsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,30 @@ class StringsTest {
assertEquals("A", Strings.limit("A", 1, false))
}

@Test
fun truncateMiddle() {
assertEquals("", Strings.truncateMiddle(null, 4, 4))
assertEquals("", Strings.truncateMiddle(null, -4, 4))
assertEquals("", Strings.truncateMiddle(null, 4, -4))
assertEquals("", Strings.truncateMiddle("", 4, 4))
assertEquals("", Strings.truncateMiddle("", -4, 4))
assertEquals("", Strings.truncateMiddle("", 4, -4))
assertEquals("", Strings.truncateMiddle("1234-6789", -4, 4))
assertEquals("", Strings.truncateMiddle("1234-6789", 4, -4))
assertEquals("", Strings.truncateMiddle("1234-6789", -4, -4))
assertEquals("", Strings.truncateMiddle("1234-6789", 0, 0))
assertEquals("1234-6789", Strings.truncateMiddle("1234-6789", 40, 0))
assertEquals("1234-6789", Strings.truncateMiddle("1234-6789", 0, 40))
assertEquals("1234-6789", Strings.truncateMiddle("1234-6789", 5, 4))
assertEquals("1234-6789", Strings.truncateMiddle("1234-6789", 4, 5))
assertEquals("1234-6789", Strings.truncateMiddle("1234-6789", 4, 4))
assertEquals("1234-6789", Strings.truncateMiddle("1234-6789", 0, 4))
assertEquals("1234-6789", Strings.truncateMiddle("1234-6789", 4, 0))
assertEquals("123-456", Strings.truncateMiddle("123-456", 1, 1))
assertEquals("1234…[…]…6789", Strings.truncateMiddle("123456789-123456789-123456789", 4, 4))
assertEquals("…[…]…6789", Strings.truncateMiddle("123456789-123456789-123456789", 0, 4))
assertEquals("1234…[…]…", Strings.truncateMiddle("123456789-123456789-123456789", 4, 0))
assertEquals("1…[…]…9", Strings.truncateMiddle("123456789-123456789-123456789", 1, 1))
assertEquals("12345678901234", Strings.truncateMiddle("12345678901234", 6, 6))
}
}

0 comments on commit 8faf6b9

Please sign in to comment.