Author: niallp Date: Thu Jan 28 17:27:57 2010 New Revision: 904175 URL: http://svn.apache.org/viewvc?rev=904175&view=rev Log: Port LANG-405 to 2.x branch - add a abbreviateMiddle() method to StringUtils
Modified: commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/StringUtils.java commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/StringUtilsTest.java Modified: commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/StringUtils.java URL: http://svn.apache.org/viewvc/commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/StringUtils.java?rev=904175&r1=904174&r2=904175&view=diff ============================================================================== --- commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/StringUtils.java (original) +++ commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/StringUtils.java Thu Jan 28 17:27:57 2010 @@ -5725,6 +5725,55 @@ } return "..." + str.substring(str.length() - (maxWidth - 3)); } + + /** + * <p>Abbreviates a String to the length passed, replacing the middle characters with the supplied + * replacement String.</p> + * + * <p>This abbreviation only occurs if the following criteria is met: + * <ul> + * <li>Neither the String for abbreviation 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 abbreviated String will have enough room for the length supplied replacement String + * and the first and last characters of the supplied String for abbreviation</li> + * </ul> + * Otherwise, the returned String will be the same as the supplied String for abbreviation. + * </p> + * + * <pre> + * StringUtils.abbreviateMiddle(null, null, 0) = null + * StringUtils.abbreviateMiddle("abc", null, 0) = "abc" + * StringUtils.abbreviateMiddle("abc", ".", 0) = "abc" + * StringUtils.abbreviateMiddle("abc", ".", 3) = "abc" + * StringUtils.abbreviateMiddle("abcdef", ".", 4) = "ab.f" + * </pre> + * + * @param str the String to abbreviate, may be null + * @param middle the String to replace the middle characters with, may be null + * @param length the length to abbreviate <code>str</code> to. + * @return the abbreviated String if the above criteria is met, or the original String supplied for abbreviation. + */ + public static String abbreviateMiddle(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; + + StringBuffer builder = new StringBuffer(length); + builder.append(str.substring(0,startOffset)); + builder.append(middle); + builder.append(str.substring(endOffset)); + + return builder.toString(); + } // Difference //----------------------------------------------------------------------- Modified: commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/StringUtilsTest.java URL: http://svn.apache.org/viewvc/commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/StringUtilsTest.java?rev=904175&r1=904174&r2=904175&view=diff ============================================================================== --- commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/StringUtilsTest.java (original) +++ commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/StringUtilsTest.java Thu Jan 28 17:27:57 2010 @@ -1614,6 +1614,46 @@ assertEquals(message, expected, actual); } + public void testAbbreviateMiddle() { + // javadoc examples + assertNull( StringUtils.abbreviateMiddle(null, null, 0) ); + assertEquals( "abc", StringUtils.abbreviateMiddle("abc", null, 0) ); + assertEquals( "abc", StringUtils.abbreviateMiddle("abc", ".", 0) ); + assertEquals( "abc", StringUtils.abbreviateMiddle("abc", ".", 3) ); + assertEquals( "ab.f", StringUtils.abbreviateMiddle("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.abbreviateMiddle( + "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.abbreviateMiddle( longText, "->", 22 ) ); + + // Test negative length + assertEquals("abc", StringUtils.abbreviateMiddle("abc", ".", -1)); + + // Test boundaries + // Fails to change anything as method ensures first and last char are kept + assertEquals("abc", StringUtils.abbreviateMiddle("abc", ".", 1)); + assertEquals("abc", StringUtils.abbreviateMiddle("abc", ".", 2)); + + // Test length of n=1 + assertEquals("a", StringUtils.abbreviateMiddle("a", ".", 1)); + + // Test smallest length that can lead to success + assertEquals("a.d", StringUtils.abbreviateMiddle("abcd", ".", 3)); + + // More from LANG-405 + assertEquals("a..f", StringUtils.abbreviateMiddle("abcdef", "..", 4)); + assertEquals("ab.ef", StringUtils.abbreviateMiddle("abcdef", ".", 5)); + } + //----------------------------------------------------------------------- public void testDifference_StringString() { assertEquals(null, StringUtils.difference(null, null));