diff --git a/src/java/org/apache/commons/lang/StringUtils.java b/src/java/org/apache/commons/lang/StringUtils.java index 987d8c704..51f439a96 100644 --- a/src/java/org/apache/commons/lang/StringUtils.java +++ b/src/java/org/apache/commons/lang/StringUtils.java @@ -76,10 +76,30 @@ import java.util.StringTokenizer; * @author Henning P. Schmiedehausen * @author Arun Mammen Thomas * @since 1.0 - * @version $Id: StringUtils.java,v 1.43 2003/04/10 00:01:21 ggregory Exp $ + * @version $Id: StringUtils.java,v 1.44 2003/04/16 04:37:33 bayard Exp $ */ public class StringUtils { + /** + *

The maximum size to which the padding constant(s) can expand.

+ */ + private static int PAD_LIMIT = 8192; + + /** + *

A String containing all blank characters.

+ * + *

Used for efficient blank padding. The length of the string expands as needed.

+ */ + private static String blanks = new String(" "); + + /** + *

An array of Strings used for padding.

+ * + *

Used for efficient blank padding. The length of each string expands as needed.

+ */ + private final static String[] padding = new String[Character.MAX_VALUE]; + // String.concat about twice as fast as StringBuffer.append + /** *

StringUtils instances should NOT be constructed in * standard programming. Instead, the class should be used as @@ -1178,6 +1198,10 @@ public class StringUtils { * @throws NullPointerException if str is null */ public static String repeat(String str, int repeat) { + if (str.length() == 1 && repeat <= PAD_LIMIT) { + return padding(repeat, str.charAt(0)); + } + StringBuffer buffer = new StringBuffer(repeat * str.length()); for (int i = 0; i < repeat; i++) { buffer.append(str); @@ -1185,20 +1209,84 @@ public class StringUtils { return buffer.toString(); } + /** + *

Returns blank padding with a given length.

+ * + * @param repeat number of times to repeat a blank + * @return String with repeated character + * @throws IndexOutOfBoundsException if repeat < 0 + */ + private static String padding(int repeat) { + while (blanks.length() < repeat) { + blanks = blanks.concat(blanks); + } + return blanks.substring(0, repeat); + } + + /** + *

Returns padding using the specified delimiter repeated to a given length. + *

+ * + * @param repeat number of times to repeat delim + * @param delim character to repeat + * @return String with repeated character + * @throws NullPointerException if delim is null + * @throws IndexOutOfBoundsException if repeat < 0 + */ + + private static String padding(int repeat, char delim) { + if (padding[delim] == null) { + padding[delim] = String.valueOf(delim); + } + while (padding[delim].length() < repeat) { + padding[delim] = padding[delim].concat(padding[delim]); + } + return padding[delim].substring(0, repeat); + } + /** *

Right pad a String with spaces.

* *

The String is padded to the size of n.

* - * @param str String to repeat + * @param str String to pad out * @param size number of times to repeat str - * @return right padded String + * @return right padded String or original String if no padding is necessary * @throws NullPointerException if str is null */ public static String rightPad(String str, int size) { - return rightPad(str, size, " "); + int pads = size - str.length(); + if (pads <= 0) { + return str; // returns original string when possible + } + if (pads > PAD_LIMIT) { + return rightPad(str, size, " "); + } + return str + padding(pads); } - + + /** + *

Right pad a String with a specified character.

+ * + *

The String is padded to the size of n.

+ * + * @param str String to pad out + * @param size size to pad to + * @param delim character to pad with + * @return right padded String or original String if no padding is necessary + * @throws NullPointerException if str or delim is null + */ + public static String rightPad(String str, int size, char delim) { + int pads = size - str.length(); + if (pads <= 0) { + return str; // returns original string when possible + } + if (pads > PAD_LIMIT) { + return rightPad(str, size, String.valueOf(delim)); + } + return str + padding(pads, delim); + } + /** *

Right pad a String with a specified string.

* @@ -1207,11 +1295,15 @@ public class StringUtils { * @param str String to pad out * @param size size to pad to * @param delim String to pad with - * @return right padded String + * @return right padded String or original String if no padding is necessary * @throws NullPointerException if str or delim is null * @throws ArithmeticException if delim is the empty String */ public static String rightPad(String str, int size, String delim) { + if (delim.length() == 1 && size - str.length() <= PAD_LIMIT) { + return rightPad(str, size, delim.charAt(0)); + } + size = (size - str.length()) / delim.length(); if (size > 0) { str += repeat(delim, size); @@ -1226,23 +1318,53 @@ public class StringUtils { * * @param str String to pad out * @param size size to pad to - * @return left padded String + * @return left padded String or original String if no padding is necessary * @throws NullPointerException if str or delim is null */ public static String leftPad(String str, int size) { - return leftPad(str, size, " "); + int pads = size - str.length(); + if (pads <= 0) { + return str; // returns original string when possible + } + if (pads > PAD_LIMIT) { + return leftPad(str, size, " "); + } + return padding(pads).concat(str); } + + /** + * Left pad a String with a specified character. Pad to a size of n. + * + * @param str String to pad out + * @param size size to pad to + * @param delim character to pad with + * @return left padded String or original String if no padding is necessary + * @throws NullPointerException if str or delim is null + */ + public static String leftPad(String str, int size, char delim) { + int pads = size - str.length(); + if (pads <= 0) { + return str; // returns original string when possible + } + if (pads > PAD_LIMIT) { + return leftPad(str, size, " "); + } + return padding(pads, delim).concat(str); + } + /** * Left pad a String with a specified string. Pad to a size of n. * * @param str String to pad out * @param size size to pad to * @param delim String to pad with - * @return left padded String + * @return left padded String or original String if no padding is necessary * @throws NullPointerException if str or delim is null * @throws ArithmeticException if delim is the empty string */ public static String leftPad(String str, int size, String delim) { + if (delim.length() == 1 && size - str.length() <= PAD_LIMIT) + return leftPad(str, size, delim.charAt(0)); size = (size - str.length()) / delim.length(); if (size > 0) { str = repeat(delim, size) + str; @@ -1813,6 +1935,7 @@ public class StringUtils { * @param validChars an array of valid chars * @return true if it only contains valid chars and is non-null */ + /* rewritten public static boolean containsOnly(String str, char[] validChars) { if (str == null || validChars == null) { return false; @@ -1834,6 +1957,7 @@ public class StringUtils { } return true; } + */ /** *

Checks that the String does not contain certain chars.

@@ -1873,6 +1997,66 @@ public class StringUtils { return true; } + /** + *

Checks if the String contains only certain chars.

+ * + * @param str the String to check + * @param valid an array of valid chars + * @return true if it only contains valid chars and is non-null + */ + public static boolean containsOnly(String str, char[] valid) { + // All these pre-checks are to maintain API with an older version + if( (valid == null) || (str == null) ) { + return false; + } + if(str.length() == 0) { + return true; + } + if(valid.length == 0) { + return false; + } + return indexOfAnyBut(str, valid) == -1; + } + + /** + *

Search a String to find the first index of any + * character not in the given set of characters.

+ * + * @param str the String to check + * @param searchChars the chars to search for + * @return the index of any of the chars + * @throws NullPointerException if either str or searchChars is null + */ + public static int indexOfAnyBut(String str, char[] searchChars) { + if(searchChars == null) { + return -1; + } + return indexOfAnyBut(str, new String(searchChars)); + } + + /** + *

Search a String to find the first index of any + * character not in the given set of characters.

+ * + * @param str the String to check + * @param searchChars a String containing the chars to search for + * @return the last index of any of the chars + * @throws NullPointerException if either str or searchChars is null + */ + public static int indexOfAnyBut(String str, String searchChars) { + if (str == null || searchChars == null) { + return -1; + } + + for (int i = 0; i < str.length(); i ++) { + if (searchChars.indexOf(str.charAt(i)) < 0) { + return i; + } + } + + return -1; + } + // Defaults //-------------------------------------------------------------------------- @@ -1955,7 +2139,7 @@ public class StringUtils { * In no case will it return a string of length greater than maxWidth. * * @param maxWidth maximum length of result string - **/ + */ public static String abbreviate(String s, int maxWidth) { return abbreviate(s, 0, maxWidth); } @@ -1971,7 +2155,7 @@ public class StringUtils { * * @param offset left edge of source string * @param maxWidth maximum length of result string - **/ + */ public static String abbreviate(String s, int offset, int maxWidth) { if (maxWidth < 4) throw new IllegalArgumentException("Minimum abbreviation width is 4"); @@ -2103,3 +2287,4 @@ public class StringUtils { } } + diff --git a/src/test/org/apache/commons/lang/StringUtilsTest.java b/src/test/org/apache/commons/lang/StringUtilsTest.java index 93fb74eab..955753b20 100644 --- a/src/test/org/apache/commons/lang/StringUtilsTest.java +++ b/src/test/org/apache/commons/lang/StringUtilsTest.java @@ -69,7 +69,7 @@ import junit.textui.TestRunner; * @author Henning P. Schmiedehausen - * @version $Id: StringUtilsTest.java,v 1.18 2003/04/09 18:45:29 alex Exp $ + * @version $Id: StringUtilsTest.java,v 1.19 2003/04/16 04:37:33 bayard Exp $ */ public class StringUtilsTest extends TestCase { @@ -564,6 +564,31 @@ public class StringUtilsTest extends TestCase { assertEquals("containsNone(str3, chars3)", true, StringUtils.containsNone(str3, chars3)); } + public void testIndexOfAnyBut() { + String str1 = "a"; + String str2 = "b"; + String str3 = "ab"; + String chars1= "b"; + String chars2= "a"; + String chars3= "ab"; + String emptyChars = ""; + assertEquals("indexOfAnyBut(null, null)", -1, StringUtils.indexOfAnyBut(null, (String) null)); + assertEquals("indexOfAnyBut(empty-string, null)", -1, StringUtils.indexOfAnyBut("", (String) null)); + assertEquals("indexOfAnyBut(null, empty-string)", -1, StringUtils.indexOfAnyBut(null, emptyChars)); + assertEquals("indexOfAnyBut(str1, empty-char-array)", 0, StringUtils.indexOfAnyBut(str1, emptyChars)); + assertEquals("indexOfAnyBut(empty-string, empty-char-array)", -1, StringUtils.indexOfAnyBut("", emptyChars)); + assertEquals("indexOfAnyBut(empty-string, chars1)", -1, StringUtils.indexOfAnyBut("", chars1)); + assertEquals("indexOfAnyBut(str1, chars1)", 0, StringUtils.indexOfAnyBut(str1, chars1)); + assertEquals("indexOfAnyBut(str1, chars2)", -1, StringUtils.indexOfAnyBut(str1, chars2)); + assertEquals("indexOfAnyBut(str1, chars3)", -1, StringUtils.indexOfAnyBut(str1, chars3)); + assertEquals("indexOfAnyBut(str2, chars1)", -1, StringUtils.indexOfAnyBut(str2, chars1)); + assertEquals("indexOfAnyBut(str2, chars2)", 0, StringUtils.indexOfAnyBut(str2, chars2)); + assertEquals("indexOfAnyBut(str2, chars3)", -1, StringUtils.indexOfAnyBut(str2, chars3)); + assertEquals("indexOfAnyBut(String3, chars1)", 0, StringUtils.indexOfAnyBut(str3, chars1)); + assertEquals("indexOfAnyBut(String3, chars2)", 1, StringUtils.indexOfAnyBut(str3, chars2)); + assertEquals("indexOfAnyBut(String3, chars3)", -1, StringUtils.indexOfAnyBut(str3, chars3)); + } + public void testAbbreviate() { assertEquals("abbreviate(String,int) failed",