alex 2003/03/29 08:17:21
Modified: lang/src/java/org/apache/commons/lang StringUtils.java
lang/src/test/org/apache/commons/lang StringUtilsTest.java
Log:
changed chomp() to match Perl
deprecated chomp* methods in favor of new slice methods
improved unit tests and documentation
Revision Changes Path
1.40 +162 -23
jakarta-commons/lang/src/java/org/apache/commons/lang/StringUtils.java
Index: StringUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/StringUtils.java,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- StringUtils.java 25 Mar 2003 00:15:58 -0000 1.39
+++ StringUtils.java 29 Mar 2003 16:17:21 -0000 1.40
@@ -820,36 +820,72 @@
// Chomping
//--------------------------------------------------------------------------
-
- /**
- * <p>Remove the last newline, and everything after it from a String.</p>
+
+ /**
+ * <p>Remove one newline from end of a String if it's there,
+ * otherwise leave it alone. A newline is "\n", "\r", or "\r\n".
+ * <p>
+ * Note that this behavior has changed from 1.0. It
+ * now more closely matches Perl chomp. For the previous behavior,
+ * use slice(String).
*
- * @param str String to chomp the newline from
- * @return String without chomped newline
+ * @param str String to chomp a newline from
+ * @return String without newline
* @throws NullPointerException if str is <code>null</code>
*/
public static String chomp(String str) {
- return chomp(str, "\n");
+ if (str.length() == 0) {
+ return str;
+ }
+
+ if (str.length() == 1) {
+ if ("\r".equals(str) || "\n".equals(str)) {
+ return "";
+ }
+ else {
+ return str;
+ }
+ }
+
+ int lastIdx = str.length() - 1;
+ char last = str.charAt(lastIdx);
+
+ if (last == '\n') {
+ if (str.charAt(lastIdx - 1) == '\r') {
+ lastIdx--;
+ }
+ } else if (last == '\r') {
+
+ } else {
+ lastIdx++;
+ }
+ return str.substring(0, lastIdx);
}
-
- /**
- * <p>Remove the last value of a supplied String, and everything after
- * it from a String.</p>
+
+ /**
+ * <p>Remove one string (the separator) from the end of another
+ * string if it's there, otherwise leave it alone.
+ * <p>
*
- * @param str String to chomp from
- * @param sep String to chomp
- * @return String without chomped ending
- * @throws NullPointerException if str or sep is <code>null</code>
+ * Note that this behavior has changed from 1.0. It
+ * now more closely matches Perl chomp. For the previous behavior,
+ * use slice(String,String).
+ *
+ * @param str string to chomp from
+ * @param separator separator string
+ * @return String without trailing separator
+ * @throws NullPointerException if str is <code>null</code>
*/
- public static String chomp(String str, String sep) {
- int idx = str.lastIndexOf(sep);
- if (idx != -1) {
- return str.substring(0, idx);
- } else {
+ public static String chomp(String str, String separator) {
+ if (str.length() == 0) {
return str;
}
+ if (str.endsWith(separator)) {
+ return str.substring(0, str.length() - separator.length());
+ }
+ return str;
}
-
+
/**
* <p>Remove a newline if and only if it is at the end
* of the supplied String.</p>
@@ -857,6 +893,7 @@
* @param str String to chomp from
* @return String without chomped ending
* @throws NullPointerException if str is <code>null</code>
+ * @deprecated use chomp(String) instead
*/
public static String chompLast(String str) {
return chompLast(str, "\n");
@@ -869,6 +906,7 @@
* @param sep String to chomp
* @return String without chomped ending
* @throws NullPointerException if str or sep is <code>null</code>
+ * @deprecated use chomp(String,String) instead
*/
public static String chompLast(String str, String sep) {
if (str.length() == 0) {
@@ -884,12 +922,14 @@
/**
* <p>Remove everything and return the last value of a supplied String, and
- * everything after it from a String.</p>
+ * everything after it from a String.
+ * [That makes no sense. Just use sliceRemainder() :-)]</p>
*
* @param str String to chomp from
* @param sep String to chomp
* @return String chomped
* @throws NullPointerException if str or sep is <code>null</code>
+ * @deprecated use sliceRemainder(String,String) instead
*/
public static String getChomp(String str, String sep) {
int idx = str.lastIndexOf(sep);
@@ -910,6 +950,7 @@
* @param sep String to chomp
* @return String without chomped beginning
* @throws NullPointerException if str or sep is <code>null</code>
+ * @deprecated use sliceFirstRemainder(String,String) instead
*/
public static String prechomp(String str, String sep) {
int idx = str.indexOf(sep);
@@ -928,6 +969,7 @@
* @param sep String to chomp
* @return String prechomped
* @throws NullPointerException if str or sep is <code>null</code>
+ * @deprecated use sliceFirst(String) instead
*/
public static String getPrechomp(String str, String sep) {
int idx = str.indexOf(sep);
@@ -976,6 +1018,7 @@
* @param str String to chop a newline from
* @return String without newline
* @throws NullPointerException if str is <code>null</code>
+ * @deprecated use chomp(String) instead
*/
public static String chopNewline(String str) {
int lastIdx = str.length() - 1;
@@ -990,6 +1033,102 @@
return str.substring(0, lastIdx);
}
+
+ // Slicing
+ //--------------------------------------------------------------------------
+
+ /**
+ * <p>Remove the last newline, and everything after it from a String.</p>
+ * (This method was formerly named chomp or chopNewline.)
+ *
+ * @param str String to slice the newline from
+ * @return String without sliced newline
+ * @throws NullPointerException if str is <code>null</code>
+ */
+ public static String slice(String str) {
+ return slice(str, "\n");
+ }
+
+ /**
+ * <p>Find the last occurence of a separator String;
+ * remove it and everything after it.</p>
+ * (This method was formerly named chomp.)
+ *
+ * @param str String to slice from
+ * @param sep String to slice
+ * @return String without sliced ending
+ * @throws NullPointerException if str or sep is <code>null</code>
+ */
+ public static String slice(String str, String sep) {
+ int idx = str.lastIndexOf(sep);
+ if (idx != -1) {
+ return str.substring(0, idx);
+ } else {
+ return str;
+ }
+ }
+
+ /**
+ * <p>Find the last occurence of a separator String, and return
+ * everything after it.</p>
+ * (This method was formerly named getchomp. Also, now it does not
+ * include the separator in the return value.)
+ *
+ * @param str String to slice from
+ * @param sep String to slice
+ * @return String sliced
+ * @throws NullPointerException if str or sep is <code>null</code>
+ */
+ public static String sliceRemainder(String str, String sep) {
+ int idx = str.lastIndexOf(sep);
+ if (idx == str.length() - sep.length()) {
+ return "";
+ } else if (idx != -1) {
+ return str.substring(idx + sep.length());
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * <p>Find the first occurence of a separator String, and return
+ * everything after it.</p>
+ * (This method was formerly named prechomp. Also, previously
+ * it included the separator in the return value; now it does not.)
+ *
+ * @param str String to slice from
+ * @param sep String to slice
+ * @return String without sliced beginning
+ * @throws NullPointerException if str or sep is <code>null</code>
+ */
+ public static String sliceFirstRemainder(String str, String sep) {
+ int idx = str.indexOf(sep);
+ if (idx != -1) {
+ return str.substring(idx + sep.length());
+ } else {
+ return str;
+ }
+ }
+
+ /**
+ * <p>Find the first occurence of a separator string;
+ * return everything before it (but not including the separator).</p>
+ * (This method was formerly named getPrechomp. Also, it used to
+ * include the separator, but now it does not.)
+ *
+ * @param str String to slice from
+ * @param sep String to slice
+ * @return String presliced
+ * @throws NullPointerException if str or sep is <code>null</code>
+ */
+ public static String sliceFirst(String str, String sep) {
+ int idx = str.indexOf(sep);
+ if (idx != -1) {
+ return str.substring(0, idx);
+ } else {
+ return "";
+ }
+ }
// Conversion
//--------------------------------------------------------------------------
1.17 +91 -17
jakarta-commons/lang/src/test/org/apache/commons/lang/StringUtilsTest.java
Index: StringUtilsTest.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/lang/src/test/org/apache/commons/lang/StringUtilsTest.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- StringUtilsTest.java 23 Mar 2003 21:51:19 -0000 1.16
+++ StringUtilsTest.java 29 Mar 2003 16:17:21 -0000 1.17
@@ -153,7 +153,7 @@
}
public void testJoin() {
- assertEquals("concatenate(Object[]) failed",
+ assertEquals("concatenate(Object[]) failed",
TEXT_LIST_NOSEP, StringUtils.concatenate(ARRAY_LIST));
assertEquals("join(Object[], String) failed", TEXT_LIST,
StringUtils.join(ARRAY_LIST, SEPARATOR));
@@ -173,7 +173,7 @@
StringUtils.join(Arrays.asList(ARRAY_LIST).iterator(),
null));
- assertEquals("concatenate(Object[]) failed",
+ assertEquals("concatenate(Object[]) failed",
"", StringUtils.concatenate(EMPTY_ARRAY_LIST));
assertEquals("join(Object[], String) failed", "",
StringUtils.join(EMPTY_ARRAY_LIST, SEPARATOR));
@@ -268,10 +268,7 @@
" "+FOO+" ", StringUtils.center(FOO, 9) );
}
- public void testChompFunctions() {
- assertEquals("chomp(String) failed",
- FOO, StringUtils.chomp(FOO + "\n" + FOO) );
-
+ public void testDeprecatedChompFunctions() {
assertEquals("chompLast(String) failed",
FOO, StringUtils.chompLast(FOO + "\n") );
@@ -284,13 +281,90 @@
assertEquals("getPrechomp(String, String) failed",
FOO + "\n", StringUtils.getPrechomp(FOO + "\n" + FOO, "\n") );
- assertEquals("chop(String, String) failed",
- FOO, StringUtils.chop(FOO + "\r\n") );
-
assertEquals("chopNewline(String, String) failed",
FOO, StringUtils.chopNewline(FOO + "\r\n") );
}
+ public void testChop() {
+
+ String[][] chopCases = {
+ { FOO + "\r\n", FOO } ,
+ { FOO + "\n" , FOO } ,
+ { FOO + "\r", FOO },
+ { "foo", "fo"},
+ { "foo\nfoo", "foo\nfo" },
+ { "\n", "" },
+ { "\r", "" },
+ { "\r\n", "" },
+ };
+ for (int i = 0; i < chopCases.length; i++) {
+ String original = chopCases[i][0];
+ String expectedResult = chopCases[i][1];
+ assertEquals("chop(String) failed",
+ expectedResult, StringUtils.chop(original));
+ }
+ }
+
+ public void testChomp() {
+
+ String[][] chompCases = {
+ { FOO + "\r\n", FOO } ,
+ { FOO + "\n" , FOO } ,
+ { FOO + "\r", FOO },
+ { FOO, FOO },
+ { FOO + "\n\n", FOO + "\n"},
+ { "foo\nfoo", "foo\nfoo" },
+ { "\n", "" },
+ { "\r", "" },
+ { "\r\n", "" },
+ };
+ for (int i = 0; i < chompCases.length; i++) {
+ String original = chompCases[i][0];
+ String expectedResult = chompCases[i][1];
+ assertEquals("chomp(String) failed",
+ expectedResult, StringUtils.chomp(original));
+ }
+
+ assertEquals("chomp(String, String) failed",
+ "foo", StringUtils.chomp("foobar", "bar"));
+ assertEquals("chomp(String, String) failed",
+ "foobar", StringUtils.chomp("foobar", "baz"));
+ assertEquals("chomp(String, String) failed",
+ "foo", StringUtils.chomp("foo", "foooo"));
+ }
+
+ public void testSliceFunctions() {
+
+ String[][] sliceCases = {
+ {"foo\n", "foo"},
+ {"foo\nbar", "foo"},
+ {"foo\nbar\n", "foo\nbar"},
+ {"foo\nbar\nbaz", "foo\nbar"},
+ };
+ for (int i = 0; i < sliceCases.length; i++) {
+ String original = sliceCases[i][0];
+ String expectedResult = sliceCases[i][1];
+ assertEquals("slice(String) failed",
+ expectedResult, StringUtils.slice(original));
+ }
+
+ String original = "fooXXbarXXbaz";
+ String sep = "XX";
+
+ assertEquals("slice(String,String) failed",
+ "fooXXbar", StringUtils.slice(original, sep) );
+
+ assertEquals("sliceRemainder(String, String) failed",
+ "baz", StringUtils.sliceRemainder(original, sep) );
+
+ assertEquals("sliceFirst(String, String) failed",
+ "foo", StringUtils.sliceFirst(original, sep) );
+
+ assertEquals("sliceFirstRemainder(String, String) failed",
+ "barXXbaz", StringUtils.sliceFirstRemainder(original, sep) );
+
+ }
+
public void testPadFunctions() {
assertEquals("rightPad(String, int) failed",
"1234 ", StringUtils.rightPad ("1234", 8) );
@@ -317,13 +391,13 @@
assertEquals("reverse(empty-string) failed",
"", StringUtils.reverse("") );
assertEquals("reverseDelimitedString(String,'.') failed",
- "org.apache.test",
+ "org.apache.test",
StringUtils.reverseDelimitedString("test.apache.org", ".") );
assertEquals("reverseDelimitedString(empty-string,'.') failed",
- "",
+ "",
StringUtils.reverseDelimitedString("", ".") );
assertEquals("reverseDelimitedString(String,' ') failed",
- "once upon a time",
+ "once upon a time",
StringUtils.reverseDelimitedString("time a upon once"," ") );
}
@@ -359,13 +433,13 @@
"\\u0234", StringUtils.escape("\u0234") );
assertEquals("escape(String) failed",
"\\u00fd", StringUtils.escape("\u00fd") );
- assertEquals("unescape(String) failed",
+ assertEquals("unescape(String) failed",
"", StringUtils.unescape("") );
- assertEquals("unescape(String) failed",
+ assertEquals("unescape(String) failed",
"test", StringUtils.unescape("test") );
- assertEquals("unescape(String) failed",
+ assertEquals("unescape(String) failed",
"\ntest\b", StringUtils.unescape("\\ntest\\b") );
- assertEquals("unescape(String) failed",
+ assertEquals("unescape(String) failed",
"\u123425foo\ntest\b",
StringUtils.unescape("\\u123425foo\\ntest\\b") );
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]