Repository: commons-lang Updated Branches: refs/heads/master de0819cb8 -> 6838ba320
LANG-1013: Add StringUtils.truncate() (closes #137) Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/c6fac966 Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/c6fac966 Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/c6fac966 Branch: refs/heads/master Commit: c6fac966ab314769d27e117bab05aee1a72df760 Parents: de0819c Author: Thiago Andrade <[email protected]> Authored: Sun Apr 24 14:34:48 2016 -0300 Committer: pascalschumacher <[email protected]> Committed: Sun Jun 5 21:25:18 2016 +0200 ---------------------------------------------------------------------- .../org/apache/commons/lang3/StringUtils.java | 115 ++++++++++++ .../apache/commons/lang3/StringUtilsTest.java | 177 +++++++++++++++++++ 2 files changed, 292 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-lang/blob/c6fac966/src/main/java/org/apache/commons/lang3/StringUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java b/src/main/java/org/apache/commons/lang3/StringUtils.java index d4fdcf2..e2e928a 100644 --- a/src/main/java/org/apache/commons/lang3/StringUtils.java +++ b/src/main/java/org/apache/commons/lang3/StringUtils.java @@ -460,6 +460,121 @@ public class StringUtils { return str == null ? EMPTY : str.trim(); } + /** + * <p>Truncates a String. This will turn + * "Now is the time for all good men" into "Now is the time for".</p> + * + * <p>Specifically:</p> + * <ul> + * <li>If {@code str} is less than {@code maxWidth} characters + * long, return it.</li> + * <li>Else truncate it to {@code substring(str, 0, maxWidth)}.</li> + * <li>If {@code maxWidth} is less than {@code 0}, throw an + * {@code IllegalArgumentException}.</li> + * <li>In no case will it return a String of length greater than + * {@code maxWidth}.</li> + * </ul> + * + * <pre> + * StringUtils.truncate(null, 0) = null + * StringUtils.truncate(null, 2) = null + * StringUtils.truncate("", 4) = "" + * StringUtils.truncate("abcdefg", 4) = "abcd" + * StringUtils.truncate("abcdefg", 6) = "abcdef" + * StringUtils.truncate("abcdefg", 7) = "abcdefg" + * StringUtils.truncate("abcdefg", 8) = "abcdefg" + * StringUtils.truncate("abcdefg", -1) = throws an IllegalArgumentException + * </pre> + * + * @param str the String to truncate, may be null + * @param maxWidth maximum length of result String, must be positive + * @return truncated String, {@code null} if null String input + * @since 3.5 + */ + public static String truncate(final String str, int maxWidth) { + return truncate(str, 0, maxWidth); + } + + /** + * <p>Truncates a String. This will turn + * "Now is the time for all good men" into "is the time for all".</p> + * + * <p>Works like {@code truncate(String, int)}, but allows you to specify + * a "left edge" offset. + * + * <p>Specifically:</p> + * <ul> + * <li>If {@code str} is less than {@code maxWidth} characters + * long, return it.</li> + * <li>Else truncate it to {@code substring(str, offset, maxWidth)}.</li> + * <li>If {@code maxWidth} is less than {@code 0}, throw an + * {@code IllegalArgumentException}.</li> + * <li>If {@code offset} is less than {@code 0}, throw an + * {@code IllegalArgumentException}.</li> + * <li>In no case will it return a String of length greater than + * {@code maxWidth}.</li> + * </ul> + * + * <pre> + * StringUtils.truncate(null, 0, 0) = null + * StringUtils.truncate(null, 2, 4) = null + * StringUtils.truncate("", 0, 10) = "" + * StringUtils.truncate("", 2, 10) = "" + * StringUtils.truncate("abcdefghij", 0, 3) = "abc" + * StringUtils.truncate("abcdefghij", 5, 6) = "fghij" + * StringUtils.truncate("raspberry peach", 10, 15) = "peach" + * StringUtils.truncate("abcdefghijklmno", 0, 10) = "abcdefghij" + * StringUtils.truncate("abcdefghijklmno", -1, 10) = throws an IllegalArgumentException + * StringUtils.truncate("abcdefghijklmno", Integer.MIN_VALUE, 10) = "abcdefghij" + * StringUtils.truncate("abcdefghijklmno", Integer.MIN_VALUE, Integer.MAX_VALUE) = "abcdefghijklmno" + * StringUtils.truncate("abcdefghijklmno", 0, Integer.MAX_VALUE) = "abcdefghijklmno" + * StringUtils.truncate("abcdefghijklmno", 1, 10) = "bcdefghijk" + * StringUtils.truncate("abcdefghijklmno", 2, 10) = "cdefghijkl" + * StringUtils.truncate("abcdefghijklmno", 3, 10) = "defghijklm" + * StringUtils.truncate("abcdefghijklmno", 4, 10) = "efghijklmn" + * StringUtils.truncate("abcdefghijklmno", 5, 10) = "fghijklmno" + * StringUtils.truncate("abcdefghijklmno", 5, 5) = "fghij" + * StringUtils.truncate("abcdefghijklmno", 5, 3) = "fgh" + * StringUtils.truncate("abcdefghijklmno", 10, 3) = "klm" + * StringUtils.truncate("abcdefghijklmno", 10, Integer.MAX_VALUE) = "klmno" + * StringUtils.truncate("abcdefghijklmno", 13, 1) = "n" + * StringUtils.truncate("abcdefghijklmno", 13, Integer.MAX_VALUE) = "no" + * StringUtils.truncate("abcdefghijklmno", 14, 1) = "o" + * StringUtils.truncate("abcdefghijklmno", 14, Integer.MAX_VALUE) = "o" + * StringUtils.truncate("abcdefghijklmno", 15, 1) = "" + * StringUtils.truncate("abcdefghijklmno", 15, Integer.MAX_VALUE) = "" + * StringUtils.truncate("abcdefghijklmno", Integer.MAX_VALUE, Integer.MAX_VALUE) = "" + * StringUtils.truncate("abcdefghij", 3, -1) = throws an IllegalArgumentException + * StringUtils.truncate("abcdefghij", -2, 4) = throws an IllegalArgumentException + * </pre> + * + * @param str the String to check, may be null + * @param offset left edge of source String + * @param maxWidth maximum length of result String, must be positive + * @return truncated String, {@code null} if null String input + * @since 3.5 + */ + public static String truncate(final String str, int offset, int maxWidth) { + if (offset < 0) { + throw new IllegalArgumentException("offset cannot be negative"); + } + if (maxWidth < 0) { + throw new IllegalArgumentException("maxWith cannot be negative"); + } + if (str == null) { + return null; + } + if (offset > str.length()) { + return EMPTY; + } + if (str.length() > maxWidth) { + int ix = offset + maxWidth > str.length() ? str.length() : offset + maxWidth; + return str.substring(offset, ix); + } else { + return str.substring(offset); + } + } + // Stripping //----------------------------------------------------------------------- /** http://git-wip-us.apache.org/repos/asf/commons-lang/blob/c6fac966/src/test/java/org/apache/commons/lang3/StringUtilsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java index 6c92193..0f14764 100644 --- a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java @@ -2045,6 +2045,183 @@ public class StringUtilsTest { assertEquals("ab.ef", StringUtils.abbreviateMiddle("abcdef", ".", 5)); } + @Test + public void testTruncate_StringInt() { + assertNull(StringUtils.truncate(null, 12)); + try { + StringUtils.truncate(null, -1); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate(null, -10); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate(null, Integer.MIN_VALUE); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + assertEquals("", StringUtils.truncate("", 10)); + assertEquals("", StringUtils.truncate("", 10)); + assertEquals("abc", StringUtils.truncate("abcdefghij", 3)); + assertEquals("abcdef", StringUtils.truncate("abcdefghij", 6)); + assertEquals("", StringUtils.truncate("abcdefghij", 0)); + try { + StringUtils.truncate("abcdefghij", -1); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", -100); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", Integer.MIN_VALUE); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + assertEquals("abcdefghij", StringUtils.truncate("abcdefghijklmno", 10)); + assertEquals("abcdefghijklmno", StringUtils.truncate("abcdefghijklmno", Integer.MAX_VALUE)); + assertEquals("abcde", StringUtils.truncate("abcdefghijklmno", 5)); + assertEquals("abc", StringUtils.truncate("abcdefghijklmno", 3)); + } + + @Test + public void testTruncate_StringIntInt() { + assertNull(StringUtils.truncate(null, 0, 12)); + try { + StringUtils.truncate(null, -1, 0); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate(null, -10, -4); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate(null, Integer.MIN_VALUE, Integer.MIN_VALUE); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + assertNull(StringUtils.truncate(null, 10, 12)); + assertEquals("", StringUtils.truncate("", 0, 10)); + assertEquals("", StringUtils.truncate("", 2, 10)); + assertEquals("abc", StringUtils.truncate("abcdefghij", 0, 3)); + assertEquals("fghij", StringUtils.truncate("abcdefghij", 5, 6)); + assertEquals("", StringUtils.truncate("abcdefghij", 0, 0)); + try { + StringUtils.truncate("abcdefghij", 0, -1); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", 0, -10); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", 0, -100); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", 1, -100); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", 0, Integer.MIN_VALUE); + fail("maxWith cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", -1, 0); + fail("offset cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", -10, 0); + fail("offset cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", -100, 1); + fail("offset cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", Integer.MIN_VALUE, 0); + fail("offset cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", -1, -1); + fail("offset cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", -10, -10); + fail("offset cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", -100, -100); + fail("offset cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + try { + StringUtils.truncate("abcdefghij", Integer.MIN_VALUE, Integer.MIN_VALUE); + fail("offset cannot be negative"); + } catch (Exception e) { + assertTrue(e instanceof IllegalArgumentException); + } + final String raspberry = "raspberry peach"; + assertEquals("peach", StringUtils.truncate(raspberry, 10, 15)); + assertEquals("abcdefghij", StringUtils.truncate("abcdefghijklmno", 0, 10)); + assertEquals("abcdefghijklmno", StringUtils.truncate("abcdefghijklmno", 0, Integer.MAX_VALUE)); + assertEquals("bcdefghijk", StringUtils.truncate("abcdefghijklmno", 1, 10)); + assertEquals("cdefghijkl", StringUtils.truncate("abcdefghijklmno", 2, 10)); + assertEquals("defghijklm", StringUtils.truncate("abcdefghijklmno", 3, 10)); + assertEquals("efghijklmn", StringUtils.truncate("abcdefghijklmno", 4, 10)); + assertEquals("fghijklmno", StringUtils.truncate("abcdefghijklmno", 5, 10)); + assertEquals("fghij", StringUtils.truncate("abcdefghijklmno", 5, 5)); + assertEquals("fgh", StringUtils.truncate("abcdefghijklmno", 5, 3)); + assertEquals("klm", StringUtils.truncate("abcdefghijklmno", 10, 3)); + assertEquals("klmno", StringUtils.truncate("abcdefghijklmno", 10, Integer.MAX_VALUE)); + assertEquals("n", StringUtils.truncate("abcdefghijklmno", 13, 1)); + assertEquals("no", StringUtils.truncate("abcdefghijklmno", 13, Integer.MAX_VALUE)); + assertEquals("o", StringUtils.truncate("abcdefghijklmno", 14, 1)); + assertEquals("o", StringUtils.truncate("abcdefghijklmno", 14, Integer.MAX_VALUE)); + assertEquals("", StringUtils.truncate("abcdefghijklmno", 15, 1)); + assertEquals("", StringUtils.truncate("abcdefghijklmno", 15, Integer.MAX_VALUE)); + assertEquals("", StringUtils.truncate("abcdefghijklmno", Integer.MAX_VALUE, Integer.MAX_VALUE)); + } + //----------------------------------------------------------------------- @Test public void testDifference_StringString() {
