Author: bayard Date: Thu Jan 21 08:38:12 2010 New Revision: 901595 URL: http://svn.apache.org/viewvc?rev=901595&view=rev Log: Applying Srihari Reddy's patch from LANG-405, based on Dave Meikle's original patch. This adds a truncateMiddle method to StringUtils.
Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/StringUtils.java commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/StringUtilsTest.java Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/StringUtils.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/StringUtils.java?rev=901595&r1=901594&r2=901595&view=diff ============================================================================== --- commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/StringUtils.java (original) +++ commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/StringUtils.java Thu Jan 21 08:38:12 2010 @@ -6052,4 +6052,53 @@ int strOffset = str.length() - suffix.length(); return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length()); } + + /** + * <p>Truncates a String to the length passed, replacing the middle characters with the supplied + * replacement String.</p> + * + * <p>This truncation only occurs if the following criteria is met: + * <ul> + * <li>Neither the String for truncation nor the replacement String are null or empty </li> + * <li>The length to truncate to is less than the length of the supplied String</li> + * <li>The length to truncate to is greater than 0</li> + * <li>The truncated String will have enough room for the length supplied replacement String + * and the first and last characters of the supplied String for truncation</li> + * </ul> + * Otherwise, the returned String will be the same as the supplied String for truncation. + * </p> + * + * <pre> + * StringUtils.truncateMiddle(null, null, 0) = null + * StringUtils.truncateMiddle("abc", null, 0) = "abc" + * StringUtils.truncateMiddle("abc", ".", 0) = "abc" + * StringUtils.truncateMiddle("abc", ".", 3) = "abc" + * StringUtils.truncateMiddle("abcdef", ".", 4) = "ab.f" + * </pre> + * + * @param str the String to truncate, may be null + * @param middle the String to replace the middle characters with, may be null + * @param length the length to truncate <code>str</code> to. + * @return the truncated String if the above criteria is met, or the original String supplied for truncation. + */ + public static String truncateMiddle(String str, String middle, int length) { + if (isEmpty(str) || isEmpty(middle)) { + return str; + } + + if (length >= str.length() || length < (middle.length()+2)) { + return str; + } + + int targetSting = length-middle.length(); + int startOffset = targetSting/2+targetSting%2; + int endOffset = str.length()-targetSting/2; + + StringBuilder builder = new StringBuilder(length); + builder.append(str.substring(0,startOffset)); + builder.append(middle); + builder.append(str.substring(endOffset)); + + return builder.toString(); + } } Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/StringUtilsTest.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/StringUtilsTest.java?rev=901595&r1=901594&r2=901595&view=diff ============================================================================== --- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/StringUtilsTest.java (original) +++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/StringUtilsTest.java Thu Jan 21 08:38:12 2010 @@ -1686,6 +1686,45 @@ assertEquals("queued", StringUtils.remove("queued", 'z')); } + public void testTruncateMiddle() { + // javadoc examples + assertNull( StringUtils.truncateMiddle(null, null, 0) ); + assertEquals( "abc", StringUtils.truncateMiddle("abc", null, 0) ); + assertEquals( "abc", StringUtils.truncateMiddle("abc", ".", 0) ); + assertEquals( "abc", StringUtils.truncateMiddle("abc", ".", 3) ); + assertEquals( "ab.f", StringUtils.truncateMiddle("abcdef", ".", 4) ); + + // JIRA issue (LANG-405) example (slightly different than actual expected result) + assertEquals( + "A very long text with un...f the text is complete.", + StringUtils.truncateMiddle( + "A very long text with unimportant stuff in the middle but interesting start and " + + "end to see if the text is complete.", "...", 50) ); + + // Test a much longer text :) + String longText = "Start text" + StringUtils.repeat("x", 10000) + "Close text"; + assertEquals( + "Start text->Close text", + StringUtils.truncateMiddle( longText, "->", 22 ) ); + + // Test negative length + assertEquals("abc", StringUtils.truncateMiddle("abc", ".", -1)); + + // Test boundaries + // Fails to change anything as method ensures first and last char are kept + assertEquals("abc", StringUtils.truncateMiddle("abc", ".", 1)); + assertEquals("abc", StringUtils.truncateMiddle("abc", ".", 2)); + + // Test length of n=1 + assertEquals("a", StringUtils.truncateMiddle("a", ".", 1)); + + // Test smallest length that can lead to success + assertEquals("a.d", StringUtils.truncateMiddle("abcd", ".", 3)); + + // More from LANG-405 + assertEquals("a..f", StringUtils.truncateMiddle("abcdef", "..", 4)); + assertEquals("ab.ef", StringUtils.truncateMiddle("abcdef", ".", 5)); + } public void testDifferenceAt_StringArray(){ assertEquals(-1, StringUtils.indexOfDifference(null));