commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From scolebou...@apache.org
Subject svn commit: r232652 [1/3] - in /jakarta/commons/proper/lang/trunk/src: java/org/apache/commons/lang/text/ test/org/apache/commons/lang/text/
Date Sun, 14 Aug 2005 21:45:59 GMT
Author: scolebourne
Date: Sun Aug 14 14:45:47 2005
New Revision: 232652

URL: http://svn.apache.org/viewcvs?rev=232652&view=rev
Log:
Add StrMatcher and update StrBuilder and test cases to use it, plus fix other bugs

Added:
    jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrMatcher.java   (with props)
    jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderAppendInsertTest.java   (with props)
    jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrMatcherTest.java   (with props)
Modified:
    jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java
    jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderTest.java
    jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/TextTestSuite.java

Modified: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java?rev=232652&r1=232651&r2=232652&view=diff
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java (original)
+++ jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrBuilder.java Sun Aug 14 14:45:47 2005
@@ -242,6 +242,8 @@
     /**
      * Gets the character at the specified index.
      *
+     * @see #setCharAt(int, char)
+     * @see #deleteCharAt(int)
      * @param index  the index to retrieve, must be valid
      * @return the character at the index
      * @throws IndexOutOfBoundsException if the index is invalid
@@ -256,6 +258,8 @@
     /**
      * Sets the character at the specified index.
      *
+     * @see #charAt(int)
+     * @see #deleteCharAt(int)
      * @param index  the index to set
      * @param ch  the new character
      * @throws IndexOutOfBoundsException if the index is invalid
@@ -267,6 +271,23 @@
         buffer[index] = ch;
     }
 
+    /**
+     * Deletes the character at the specified index.
+     *
+     * @see #charAt(int)
+     * @see #setCharAt(int, char)
+     * @param index  the index to delete
+     * @return this, to enable chaining
+     * @throws IndexOutOfBoundsException if the index is invalid
+     */
+    public StrBuilder deleteCharAt(int index) {
+        if (index < 0 || index >= size) {
+            throw new StringIndexOutOfBoundsException(index);
+        }
+        deleteImpl(index, index + 1, 1);
+        return this;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Copies the builder's character array into a new character array.
@@ -1025,6 +1046,19 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Internal method to delete a range without validation.
+     *
+     * @param startIndex  the start index, must be valid
+     * @param endIndex  the end index (exclusive), must be valid
+     * @param len  the length, must be valid
+     * @throws IndexOutOfBoundsException if any index is invalid
+     */
+    private void deleteImpl(int startIndex, int endIndex, int len) {
+        System.arraycopy(buffer, endIndex, buffer, startIndex, size - endIndex);
+        size -= len;
+    }
+
+    /**
      * Deletes the characters between the two specified indices.
      *
      * @param startIndex  the start index, inclusive, must be valid
@@ -1037,157 +1071,325 @@
         endIndex = validateRange(startIndex, endIndex);
         int len = endIndex - startIndex;
         if (len > 0) {
-            System.arraycopy(buffer, endIndex, buffer, startIndex, size - endIndex);
-            size -= len;
+            deleteImpl(startIndex, endIndex, len);
         }
         return this;
     }
 
+    //-----------------------------------------------------------------------
     /**
-     * Deletes the character at the specified index.
+     * Deletes the character wherever it occurs in the builder.
      *
-     * @param index  the index to delete
+     * @param ch  the character to delete
      * @return this, to enable chaining
-     * @throws IndexOutOfBoundsException if the index is invalid
      */
-    public StrBuilder deleteCharAt(int index) {
-        if (index < 0 || index >= size) {
-            throw new StringIndexOutOfBoundsException(index);
+    public StrBuilder deleteAll(char ch) {
+        for (int i = 0; i < size; i++) {
+            if (buffer[i] == ch) {
+                int start = i;
+                while (++i < size) {
+                    if (buffer[i] != ch) {
+                        break;
+                    }
+                }
+                int len = i - start;
+                deleteImpl(start, i, len);
+                i -= len;
+            }
         }
-        System.arraycopy(buffer, index + 1, buffer, index, size - index - 1);
-        size--;
         return this;
     }
 
     /**
      * Deletes the character wherever it occurs in the builder.
-     * 
+     *
      * @param ch  the character to delete
      * @return this, to enable chaining
      */
-    public StrBuilder delete(char ch) {
+    public StrBuilder deleteFirst(char ch) {
         for (int i = 0; i < size; i++) {
             if (buffer[i] == ch) {
-                int start = i;
-                while (++i < size) {
-                    if (buffer[i] != ch) {
-                        break;
-                    }
-                }
-                System.arraycopy(buffer, i, buffer, start, size - i);
-                size -= (i - start);
+                deleteImpl(i, i + 1, 1);
+                break;
             }
         }
         return this;
     }
 
+    //-----------------------------------------------------------------------
     /**
      * Deletes the string wherever it occurs in the builder.
-     * 
+     *
      * @param str  the string to delete, null causes no action
      * @return this, to enable chaining
      */
-    public StrBuilder delete(String str) {
+    public StrBuilder deleteAll(String str) {
         int len = (str == null ? 0 : str.length());
         if (len > 0) {
             int index = indexOf(str, 0);
             while (index >= 0) {
-                delete(index, index + len);
+                deleteImpl(index, index + len, len);
                 index = indexOf(str, index);
             }
         }
         return this;
     }
 
+    /**
+     * Deletes the string wherever it occurs in the builder.
+     *
+     * @param str  the string to delete, null causes no action
+     * @return this, to enable chaining
+     */
+    public StrBuilder deleteFirst(String str) {
+        int len = (str == null ? 0 : str.length());
+        if (len > 0) {
+            int index = indexOf(str, 0);
+            if (index >= 0) {
+                deleteImpl(index, index + len, len);
+            }
+        }
+        return this;
+    }
+
     //-----------------------------------------------------------------------
     /**
-     * Replaces a portion of the string builder with another string.
-     * The length of the inserted string does not have to match the removed length.
-     * 
-     * @param startIndex  the start index, inclusive, must be valid
-     * @param endIndex  the end index, exclusive, must be valid except
-     *  that if too large it is treated as end of string
-     * @param str  the string to replace with
+     * Deletes all parts of the builder that the matcher matches.
+     * <p>
+     * Matchers can be used to perform advanced deletion behaviour.
+     * For example you could write a matcher to delete all occurances
+     * where the character 'a' is followed by a number.
+     *
+     * @param matcher  the matcher to use to find the deletion, null causes no action
      * @return this, to enable chaining
-     * @throws IndexOutOfBoundsException if the index is invalid
      */
-    public StrBuilder replace(int startIndex, int endIndex, String str) {
-        endIndex = validateRange(startIndex, endIndex);
-        int insertLen = str.length();
-        int removeLen = endIndex - startIndex;
+    public StrBuilder deleteAll(StrMatcher matcher) {
+        return replace(matcher, null, 0, size, -1);
+    }
+
+    /**
+     * Deletes the first match within the builder using the specified matcher.
+     * <p>
+     * Matchers can be used to perform advanced deletion behaviour.
+     * For example you could write a matcher to delete
+     * where the character 'a' is followed by a number.
+     *
+     * @param matcher  the matcher to use to find the deletion, null causes no action
+     * @return this, to enable chaining
+     */
+    public StrBuilder deleteFirst(StrMatcher matcher) {
+        return replace(matcher, null, 0, size, 1);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Internal method to delete a range without validation.
+     *
+     * @param startIndex  the start index, must be valid
+     * @param endIndex  the end index (exclusive), must be valid
+     * @param removeLen  the length to remove (endIndex - startIndex), must be valid
+     * @param insertStr  the string to replace with, null means delete range
+     * @param insertLen  the length of the insert string, must be valid
+     * @param len  the length, must be valid
+     * @throws IndexOutOfBoundsException if any index is invalid
+     */
+    private void replaceImpl(int startIndex, int endIndex, int removeLen, String insertStr, int insertLen) {
         int newSize = size - removeLen + insertLen;
-        if (insertLen > removeLen) {
-            ensureCapacity(newSize);
-        }
         if (insertLen != removeLen) {
+            ensureCapacity(newSize);
             System.arraycopy(buffer, endIndex, buffer, startIndex + insertLen, size - endIndex);
             size = newSize;
         }
-        str.getChars(0, insertLen, buffer, startIndex);
-        return this;
+        if (insertLen > 0) {
+            insertStr.getChars(0, insertLen, buffer, startIndex);
+        }
     }
 
     /**
-     * Replaces a portion of the string builder with another string builder.
+     * Replaces a portion of the string builder with another string.
      * The length of the inserted string does not have to match the removed length.
-     * 
+     *
      * @param startIndex  the start index, inclusive, must be valid
      * @param endIndex  the end index, exclusive, must be valid except
      *  that if too large it is treated as end of string
-     * @param builder  the string builder to replace with
+     * @param replaceStr  the string to replace with, null means delete range
      * @return this, to enable chaining
      * @throws IndexOutOfBoundsException if the index is invalid
      */
-    public StrBuilder replace(int startIndex, int endIndex, StrBuilder builder) {
+    public StrBuilder replace(int startIndex, int endIndex, String replaceStr) {
         endIndex = validateRange(startIndex, endIndex);
-        int insertLen = builder.length();
-        int removeLen = endIndex - startIndex;
-        if (insertLen > removeLen) {
-            ensureCapacity(size - removeLen + insertLen);
-        }
-        if (insertLen != removeLen) {
-            //shift the current characters to the right
-            System.arraycopy(buffer, endIndex, buffer, startIndex + insertLen, size - endIndex);
-            //adjust the size accordingly
-            size += (insertLen - removeLen);
+        int insertLen = (replaceStr == null ? 0 : replaceStr.length());
+        replaceImpl(startIndex, endIndex, endIndex - startIndex, replaceStr, insertLen);
+        return this;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Replaces the search character with the replace character
+     * throughout the builder.
+     *
+     * @param search  the search character
+     * @param replace  the replace character
+     * @return this, to enable chaining
+     */
+    public StrBuilder replaceAll(char search, char replace) {
+        if (search != replace) {
+            for (int i = 0; i < size; i++) {
+                if (buffer[i] == search) {
+                    buffer[i] = replace;
+                }
+            }
         }
-        builder.getChars(0, insertLen, buffer, startIndex);
         return this;
     }
 
     /**
-     * Replaces the search character with the replace character throughout the builder.
-     * 
-     * @param search  the search string, null causes no action to occur
-     * @param replace  the replace string, null is equivalent to an empty string
+     * Replaces the first instance of the search character with the
+     * replace character in the builder.
+     *
+     * @param search  the search character
+     * @param replace  the replace character
      * @return this, to enable chaining
      */
-    public StrBuilder replace(char search, char replace) {
+    public StrBuilder replaceFirst(char search, char replace) {
         if (search != replace) {
             for (int i = 0; i < size; i++) {
                 if (buffer[i] == search) {
                     buffer[i] = replace;
+                    break;
                 }
             }
         }
         return this;
     }
 
+    //-----------------------------------------------------------------------
     /**
      * Replaces the search string with the replace string throughout the builder.
-     * 
+     *
      * @param searchStr  the search string, null causes no action to occur
      * @param replaceStr  the replace string, null is equivalent to an empty string
      * @return this, to enable chaining
      */
-    public StrBuilder replace(String searchStr, String replaceStr) {
+    public StrBuilder replaceAll(String searchStr, String replaceStr) {
         int searchLen = (searchStr == null ? 0 : searchStr.length());
         if (searchLen > 0) {
-            replaceStr = (replaceStr == null ? "" : replaceStr);
+            int replaceLen = (replaceStr == null ? 0 : replaceStr.length());
             int index = indexOf(searchStr, 0);
             while (index >= 0) {
-                replace(index, index + searchLen, replaceStr);
-                index = indexOf(searchStr, index);
+                replaceImpl(index, index + searchLen, searchLen, replaceStr, replaceLen);
+                index = indexOf(searchStr, index + replaceLen);
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Replaces the first instance of the search string with the replace string.
+     *
+     * @param searchStr  the search string, null causes no action to occur
+     * @param replaceStr  the replace string, null is equivalent to an empty string
+     * @return this, to enable chaining
+     */
+    public StrBuilder replaceFirst(String searchStr, String replaceStr) {
+        int searchLen = (searchStr == null ? 0 : searchStr.length());
+        if (searchLen > 0) {
+            int index = indexOf(searchStr, 0);
+            if (index >= 0) {
+                int replaceLen = (replaceStr == null ? 0 : replaceStr.length());
+                replaceImpl(index, index + searchLen, searchLen, replaceStr, replaceLen);
+            }
+        }
+        return this;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Replaces all matches within the builder with the replace string.
+     * <p>
+     * Matchers can be used to perform advanced replace behaviour.
+     * For example you could write a matcher to replace all occurances
+     * where the character 'a' is followed by a number.
+     *
+     * @param matcher  the matcher to use to find the deletion, null causes no action
+     * @param replaceStr  the replace string, null is equivalent to an empty string
+     * @return this, to enable chaining
+     */
+    public StrBuilder replaceAll(StrMatcher matcher, String replaceStr) {
+        return replace(matcher, replaceStr, 0, size, -1);
+    }
+
+    /**
+     * Replaces the first match within the builder with the replace string.
+     * <p>
+     * Matchers can be used to perform advanced replace behaviour.
+     * For example you could write a matcher to replace
+     * where the character 'a' is followed by a number.
+     *
+     * @param matcher  the matcher to use to find the deletion, null causes no action
+     * @param replaceStr  the replace string, null is equivalent to an empty string
+     * @return this, to enable chaining
+     */
+    public StrBuilder replaceFirst(StrMatcher matcher, String replaceStr) {
+        return replace(matcher, replaceStr, 0, size, 1);
+    }
+
+    // -----------------------------------------------------------------------
+    /**
+     * Advanced search and replaces within the builder using a matcher.
+     * <p>
+     * Matchers can be used to perform advanced behaviour.
+     * For example you could write a matcher to delete all occurances
+     * where the character 'a' is followed by a number.
+     *
+     * @param matcher  the matcher to use to find the deletion, null causes no action
+     * @param replaceStr  the string to replace the match with, null is a delete
+     * @param startIndex  the start index, inclusive, must be valid
+     * @param endIndex  the end index, exclusive, must be valid except
+     *  that if too large it is treated as end of string
+     * @param replaceCount  the number of times to replace, -1 for replace all
+     * @return this, to enable chaining
+     * @throws IndexOutOfBoundsException if start index is invalid
+     */
+    public StrBuilder replace(
+            StrMatcher matcher, String replaceStr,
+            int startIndex, int endIndex, int replaceCount) {
+        endIndex = validateRange(startIndex, endIndex);
+        return replaceImpl(matcher, replaceStr, startIndex, endIndex, replaceCount);
+    }
+
+    /**
+     * Replaces within the builder using a matcher.
+     * <p>
+     * Matchers can be used to perform advanced behaviour.
+     * For example you could write a matcher to delete all occurances
+     * where the character 'a' is followed by a number.
+     *
+     * @param matcher  the matcher to use to find the deletion, null causes no action
+     * @param replaceStr  the string to replace the match with, null is a delete
+     * @param from  the start index, must be valid
+     * @param to  the end index (exclusive), must be valid
+     * @param replaceCount  the number of times to replace, -1 for replace all
+     * @return this, to enable chaining
+     * @throws IndexOutOfBoundsException if any index is invalid
+     */
+    private StrBuilder replaceImpl(
+            StrMatcher matcher, String replaceStr,
+            int from, int to, int replaceCount) {
+        if (matcher == null || size == 0) {
+            return this;
+        }
+        int replaceLen = (replaceStr == null ? 0 : replaceStr.length());
+        char[] buf = buffer;
+        for (int i = from; i < to && replaceCount != 0; i++) {
+            int removeLen = matcher.isMatch(buf, i, from, to);
+            if (removeLen > 0) {
+                replaceImpl(i, i + removeLen, removeLen, replaceStr, replaceLen);
+                to = to - removeLen + replaceLen;
+                i = i + replaceLen - 1;
+                if (replaceCount > 0) {
+                    replaceCount--;
+                }
             }
         }
         return this;
@@ -1375,8 +1577,8 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Checks of the string builder contains the specified char.
-     * 
+     * Checks if the string builder contains the specified char.
+     *
      * @param ch  the character to find
      * @return true if the builder contains the character
      */
@@ -1391,8 +1593,8 @@
     }
 
     /**
-     * Checks of the string builder contains the specified string.
-     * 
+     * Checks if the string builder contains the specified string.
+     *
      * @param str  the string to find
      * @return true if the builder contains the string
      */
@@ -1400,6 +1602,21 @@
         return indexOf(str, 0) >= 0;
     }
 
+    /**
+     * Checks if the string builder contains a string matched using the
+     * specified matcher.
+     * <p>
+     * Matchers can be used to perform advanced searching behaviour.
+     * For example you could write a matcher to search for the character
+     * 'a' followed by a number.
+     *
+     * @param matcher  the matcher to use, null returns -1
+     * @return true if the matcher finds a match in the builder
+     */
+    public boolean contains(StrMatcher matcher) {
+        return indexOf(matcher, 0) >= 0;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Searches the string builder to find the first reference to the specified char.
@@ -1415,7 +1632,7 @@
      * Searches the string builder to find the first reference to the specified char.
      * 
      * @param ch  the character to find
-     * @param startIndex  the index to start at, must be valid
+     * @param startIndex  the index to start at, invalid index rounded to edge
      * @return the first index of the character, or -1 if not found
      */
     public int indexOf(char ch, int startIndex) {
@@ -1451,7 +1668,7 @@
      * Note that a null input string will return -1, whereas the JDK throws an exception.
      * 
      * @param str  the string to find, null returns -1
-     * @param startIndex  the index to start at, must be valid
+     * @param startIndex  the index to start at, invalid index rounded to edge
      * @return the first index of the string, or -1 if not found
      */
     public int indexOf(String str, int startIndex) {
@@ -1481,6 +1698,49 @@
         return -1;
     }
 
+    /**
+     * Searches the string builder using the matcher to find the first match.
+     * <p>
+     * Matchers can be used to perform advanced searching behaviour.
+     * For example you could write a matcher to find the character 'a'
+     * followed by a number.
+     *
+     * @param matcher  the matcher to use, null returns -1
+     * @return the first index matched, or -1 if not found
+     */
+    public int indexOf(StrMatcher matcher) {
+        return indexOf(matcher, 0);
+    }
+
+    /**
+     * Searches the string builder using the matcher to find the first
+     * match searching from the given index.
+     * <p>
+     * Matchers can be used to perform advanced searching behaviour.
+     * For example you could write a matcher to find the character 'a'
+     * followed by a number.
+     *
+     * @param matcher  the matcher to use, null returns -1
+     * @param startIndex  the index to start at, invalid index rounded to edge
+     * @return the first index matched, or -1 if not found
+     */
+    public int indexOf(StrMatcher matcher, int startIndex) {
+        startIndex = (startIndex < 0 ? 0 : startIndex);
+        if (matcher == null || startIndex >= size) {
+            return -1;
+        }
+        int len = size;
+        if (len > 0) {
+            char[] buf = buffer;
+            for (int i = startIndex; i < len; i++) {
+                if (matcher.isMatch(buf, i, startIndex, len) > 0) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Searches the string builder to find the last reference to the specified char.
@@ -1557,6 +1817,50 @@
             
         } else if (strLen == 0) {
             return startIndex;
+        }
+        return -1;
+    }
+
+    /**
+     * Searches the string builder using the matcher to find the last match.
+     * <p>
+     * Matchers can be used to perform advanced searching behaviour.
+     * For example you could write a matcher to find the character 'a'
+     * followed by a number.
+     *
+     * @param matcher  the matcher to use, null returns -1
+     * @return the last index matched, or -1 if not found
+     */
+    public int lastIndexOf(StrMatcher matcher) {
+        return lastIndexOf(matcher, size);
+    }
+
+    /**
+     * Searches the string builder using the matcher to find the last
+     * match searching from the given index.
+     * <p>
+     * Matchers can be used to perform advanced searching behaviour.
+     * For example you could write a matcher to find the character 'a'
+     * followed by a number.
+     *
+     * @param matcher  the matcher to use, null returns -1
+     * @param startIndex  the index to start at, invalid index rounded to edge
+     * @return the last index matched, or -1 if not found
+     */
+    public int lastIndexOf(StrMatcher matcher, int startIndex) {
+        startIndex = (startIndex >= size ? size - 1 : startIndex);
+        if (matcher == null || startIndex < 0) {
+            return -1;
+        }
+        int len = size;
+        if (len > 0) {
+            char[] buf = buffer;
+            int endIndex = startIndex + 1;
+            for (int i = startIndex; i >= 0; i--) {
+                if (matcher.isMatch(buf, i, 0, endIndex) > 0) {
+                    return i;
+                }
+            }
         }
         return -1;
     }

Added: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrMatcher.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrMatcher.java?rev=232652&view=auto
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrMatcher.java (added)
+++ jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrMatcher.java Sun Aug 14 14:45:47 2005
@@ -0,0 +1,405 @@
+/*
+ * Copyright 2003-2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.text;
+
+import java.util.Arrays;
+
+/**
+ * A matcher class that can be queried to determine if a character array
+ * portion matches.
+ * <p>
+ * This class comes complete with various constants and factory methods.
+ * If these do not suffice, you can subclass and implement your own matcher.
+ *
+ * @author Stephen Colebourne
+ * @since 2.2
+ * @version $Id$
+ */
+public abstract class StrMatcher {
+
+    /**
+     * Matches the comma character.
+     */
+    private static final StrMatcher COMMA_MATCHER = new CharMatcher(',');
+    /**
+     * Matches the tab character.
+     */
+    private static final StrMatcher TAB_MATCHER = new CharMatcher('\t');
+    /**
+     * Matches the space character.
+     */
+    private static final StrMatcher SPACE_MATCHER = new CharMatcher(' ');
+    /**
+     * Matches the same characters as StringTokenizer,
+     * namely space, tab, newline, formfeed.
+     */
+    private static final StrMatcher SPLIT_MATCHER = new CharSetMatcher(" \t\n\r\f".toCharArray());
+    /**
+     * Matches the String trim() whitespace characters.
+     */
+    private static final StrMatcher TRIM_MATCHER = new TrimMatcher();
+    /**
+     * Matches the double quote character.
+     */
+    private static final StrMatcher SINGLE_QUOTE_MATCHER = new CharMatcher('\'');
+    /**
+     * Matches the double quote character.
+     */
+    private static final StrMatcher DOUBLE_QUOTE_MATCHER = new CharMatcher('"');
+    /**
+     * Matches the single or double quote character.
+     */
+    private static final StrMatcher QUOTE_MATCHER = new CharSetMatcher("'\"".toCharArray());
+    /**
+     * Matches no characters.
+     */
+    private static final StrMatcher NONE_MATCHER = new NoMatcher();
+
+    // -----------------------------------------------------------------------
+
+    /**
+     * Returns a matcher which matches the comma character.
+     *
+     * @return a matcher for a comma
+     */
+    public static StrMatcher commaMatcher() {
+        return COMMA_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the tab character.
+     *
+     * @return a matcher for a tab
+     */
+    public static StrMatcher tabMatcher() {
+        return TAB_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the space character.
+     *
+     * @return a matcher for a space
+     */
+    public static StrMatcher spaceMatcher() {
+        return SPACE_MATCHER;
+    }
+
+    /**
+     * Matches the same characters as StringTokenizer,
+     * namely space, tab, newline and formfeed.
+     *
+     * @return the split matcher
+     */
+    public static StrMatcher splitMatcher() {
+        return SPLIT_MATCHER;
+    }
+
+    /**
+     * Matches the String trim() whitespace characters.
+     *
+     * @return the trim matcher
+     */
+    public static StrMatcher trimMatcher() {
+        return TRIM_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the single quote character.
+     *
+     * @return a matcher for a single quote
+     */
+    public static StrMatcher singleQuoteMatcher() {
+        return SINGLE_QUOTE_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the double quote character.
+     *
+     * @return a matcher for a double quote
+     */
+    public static StrMatcher doubleQuoteMatcher() {
+        return DOUBLE_QUOTE_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the single or double quote character.
+     *
+     * @return a matcher for a single or double quote
+     */
+    public static StrMatcher quoteMatcher() {
+        return QUOTE_MATCHER;
+    }
+
+    /**
+     * Matches no characters.
+     *
+     * @return a matcher that matches nothing
+     */
+    public static StrMatcher noneMatcher() {
+        return NONE_MATCHER;
+    }
+
+    /**
+     * Constructor that creates a matcher from a character.
+     *
+     * @param ch  the character to match, must not be null
+     * @return a new Matcher for the given char
+     */
+    public static StrMatcher charMatcher(char ch) {
+        return new CharMatcher(ch);
+    }
+
+    /**
+     * Constructor that creates a matcher from a set of characters.
+     *
+     * @param chars  the characters to match, null or empty matches nothing
+     * @return a new matcher for the given char[]
+     */
+    public static StrMatcher charSetMatcher(char[] chars) {
+        if (chars == null || chars.length == 0) {
+            return NONE_MATCHER;
+        }
+        if (chars.length == 1) {
+            return new CharMatcher(chars[0]);
+        }
+        return new CharSetMatcher(chars);
+    }
+
+    /**
+     * Constructor that creates a matcher from a string representing a set of characters.
+     *
+     * @param chars  the characters to match, null or empty matches nothing
+     * @return a new Matcher for the given characters
+     */
+    public static StrMatcher charSetMatcher(String chars) {
+        if (chars == null || chars.length() == 0) {
+            return NONE_MATCHER;
+        }
+        if (chars.length() == 1) {
+            return new CharMatcher(chars.charAt(0));
+        }
+        return new CharSetMatcher(chars.toCharArray());
+    }
+
+    /**
+     * Constructor that creates a matcher from a string.
+     *
+     * @param str  the string to match, null or empty matches nothing
+     * @return a new Matcher for the given String
+     */
+    public static StrMatcher stringMatcher(String str) {
+        if (str == null || str.length() == 0) {
+            return NONE_MATCHER;
+        }
+        return new StringMatcher(str);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Constructor.
+     */
+    protected StrMatcher() {
+        super();
+    }
+
+    /**
+     * Returns the number of matching characters, zero for no match.
+     * <p>
+     * This method is called to check for a match.
+     * The parameter <code>pos</code> represents the current position to be
+     * checked in the string <code>buffer</code> (a character array which must
+     * not be changed).
+     * The API guarantees that <code>pos</code> is a valid index for <code>buffer</code>.
+     * <p>
+     * The character array may be larger than the active area to be matched.
+     * Only values in the buffer between the specifed indices may be accessed.
+     * <p>
+     * The matching code may check one character or many.
+     * It may check characters preceeding <code>pos</code> as well as those
+     * after, so long as no checks exceed the bounds specified.
+     * <p>
+     * It must return zero for no match, or a positive number if a match was found.
+     * The number indicates the number of characters that matched.
+     *
+     * @param buffer  the text content to match against, do not change
+     * @param pos  the starting position for the match, valid for buffer
+     * @param bufferStart  the first active index in the buffer, valid for buffer
+     * @param bufferEnd  the end index (exclusive) of the active buffer, valid for buffer
+     * @return the number of matching characters, zero for no match
+     */
+    public abstract int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd);
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to define a set of characters for matching purposes.
+     */
+    static final class CharSetMatcher extends StrMatcher {
+        /** The set of characters to match. */
+        private char[] chars;
+
+        /**
+         * Constructor that creates a matcher from a character array.
+         *
+         * @param chars  the characters to match, must not be null
+         */
+        CharSetMatcher(char chars[]) {
+            super();
+            this.chars = (char[]) chars.clone();
+            Arrays.sort(this.chars);
+        }
+
+        /**
+         * Returns whether or not the given charatcer matches.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            return Arrays.binarySearch(chars, buffer[pos]) >= 0 ? 1 : 0;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to define a character for matching purposes.
+     */
+    static final class CharMatcher extends StrMatcher {
+        /** The character to match. */
+        private char ch;
+
+        /**
+         * Constructor that creates a matcher that matches a single character.
+         *
+         * @param ch  the character to match
+         */
+        CharMatcher(char ch) {
+            super();
+            this.ch = ch;
+        }
+
+        /**
+         * Returns whether or not the given character matches.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            return ch == buffer[pos] ? 1 : 0;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to define a set of characters for matching purposes.
+     */
+    static final class StringMatcher extends StrMatcher {
+        /** The string to match, as a character array. */
+        private char[] chars;
+
+        /**
+         * Constructor that creates a matcher from a String.
+         *
+         * @param str  the string to match, must not be null
+         */
+        StringMatcher(String str) {
+            super();
+            chars = str.toCharArray();
+        }
+
+        /**
+         * Returns whether or not the given text matches the stored string.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            int len = chars.length;
+            if (pos + len > bufferEnd) {
+                return 0;
+            }
+            for (int i = 0; i < chars.length; i++, pos++) {
+                if (chars[i] != buffer[pos]) {
+                    return 0;
+                }
+            }
+            return len;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to match no characters.
+     */
+    static final class NoMatcher extends StrMatcher {
+
+        /**
+         * Constructs a new instance of <code>NoMatcher</code>.
+         */
+        NoMatcher() {
+            super();
+        }
+
+        /**
+         * Always returns <code>false</code>.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            return 0;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to match whitespace as per trim().
+     */
+    static final class TrimMatcher extends StrMatcher {
+
+        /**
+         * Constructs a new instance of <code>TrimMatcher</code>.
+         */
+        TrimMatcher() {
+            super();
+        }
+
+        /**
+         * Returns whether or not the given charatcer matches.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            return buffer[pos] <= 32 ? 1 : 0;
+        }
+    }
+
+}

Propchange: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrMatcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/text/StrMatcher.java
------------------------------------------------------------------------------
    svn:keywords = "author date id revision"

Added: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderAppendInsertTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderAppendInsertTest.java?rev=232652&view=auto
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderAppendInsertTest.java (added)
+++ jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderAppendInsertTest.java Sun Aug 14 14:45:47 2005
@@ -0,0 +1,1017 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang.text;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * Unit tests for {@link org.apache.commons.lang.text.StrBuilder}.
+ *
+ * @version $Id$
+ */
+public class StrBuilderAppendInsertTest extends TestCase {
+
+    /** Test subclass of Object, with a toString method. */
+    private static Object FOO = new Object() {
+        public String toString() {
+            return "foo";
+        }
+    };
+
+    /**
+     * Main method.
+     * 
+     * @param args  command line arguments, ignored
+     */
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    /**
+     * Return a new test suite containing this test case.
+     * 
+     * @return a new test suite containing this test case
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(StrBuilderAppendInsertTest.class);
+        suite.setName("StrBuilder Tests");
+        return suite;
+    }
+
+    /**
+     * Create a new test case with the specified name.
+     * 
+     * @param name  the name
+     */
+    public StrBuilderAppendInsertTest(String name) {
+        super(name);
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendWithNullText() {
+        StrBuilder sb = new StrBuilder();
+        sb.setNullText("NULL");
+        assertEquals("", sb.toString());
+
+        sb.appendNull();
+        assertEquals("NULL", sb.toString());
+
+        sb.append((Object) null);
+        assertEquals("NULLNULL", sb.toString());
+
+        sb.append(FOO);
+        assertEquals("NULLNULLfoo", sb.toString());
+
+        sb.append((String) null);
+        assertEquals("NULLNULLfooNULL", sb.toString());
+
+        sb.append("");
+        assertEquals("NULLNULLfooNULL", sb.toString());
+
+        sb.append("bar");
+        assertEquals("NULLNULLfooNULLbar", sb.toString());
+
+        sb.append((StringBuffer) null);
+        assertEquals("NULLNULLfooNULLbarNULL", sb.toString());
+
+        sb.append(new StringBuffer("baz"));
+        assertEquals("NULLNULLfooNULLbarNULLbaz", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_Object() {
+        StrBuilder sb = new StrBuilder();
+        sb.appendNull();
+        assertEquals("", sb.toString());
+
+        sb.append((Object) null);
+        assertEquals("", sb.toString());
+
+        sb.append(FOO);
+        assertEquals("foo", sb.toString());
+
+        sb.append((StringBuffer) null);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StringBuffer("baz"));
+        assertEquals("foobaz", sb.toString());
+
+        sb.append(new StrBuilder("yes"));
+        assertEquals("foobazyes", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_String() {
+        StrBuilder sb = new StrBuilder();
+
+        sb.append("foo");
+        assertEquals("foo", sb.toString());
+
+        sb.append((String) null);
+        assertEquals("foo", sb.toString());
+
+        sb.append("");
+        assertEquals("foo", sb.toString());
+
+        sb.append("bar");
+        assertEquals("foobar", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_String_int_int() {
+        StrBuilder sb = new StrBuilder();
+        
+        sb.append("foo", 0, 3);
+        assertEquals("foo", sb.toString());
+
+        sb.append((String) null, 0, 1);
+        assertEquals("foo", sb.toString());
+
+        try {
+            sb.append("bar", -1, 1);
+            fail("append(char[], -1,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append("bar", 3, 1);
+            fail("append(char[], 3,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append("bar", 1, -1);
+            fail("append(char[],, -1) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append("bar", 1, 3);
+            fail("append(char[], 1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append("bar", -1, 3);
+            fail("append(char[], -1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append("bar", 4, 0);
+            fail("append(char[], 4, 0) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.append("bar", 3, 0);
+        assertEquals("foo", sb.toString());
+
+        sb.append("abcbardef", 3, 3);
+        assertEquals("foobar", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_StringBuffer() {
+        StrBuilder sb = new StrBuilder();
+
+        sb.append(new StringBuffer("foo"));
+        assertEquals("foo", sb.toString());
+
+        sb.append((StringBuffer) null);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StringBuffer(""));
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StringBuffer("bar"));
+        assertEquals("foobar", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_StringBuffer_int_int() {
+        StrBuilder sb = new StrBuilder();
+        
+        sb.append(new StringBuffer("foo"), 0, 3);
+        assertEquals("foo", sb.toString());
+
+        sb.append((StringBuffer) null, 0, 1);
+        assertEquals("foo", sb.toString());
+
+        try {
+            sb.append(new StringBuffer("bar"), -1, 1);
+            fail("append(char[], -1,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), 3, 1);
+            fail("append(char[], 3,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), 1, -1);
+            fail("append(char[],, -1) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), 1, 3);
+            fail("append(char[], 1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), -1, 3);
+            fail("append(char[], -1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), 4, 0);
+            fail("append(char[], 4, 0) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.append(new StringBuffer("bar"), 3, 0);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StringBuffer("abcbardef"), 3, 3);
+        assertEquals("foobar", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_StrBuilder() {
+        StrBuilder sb = new StrBuilder();
+
+        sb.append(new StrBuilder("foo"));
+        assertEquals("foo", sb.toString());
+
+        sb.append((StrBuilder) null);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StrBuilder(""));
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StrBuilder("bar"));
+        assertEquals("foobar", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_StrBuilder_int_int() {
+        StrBuilder sb = new StrBuilder();
+        
+        sb.append(new StrBuilder("foo"), 0, 3);
+        assertEquals("foo", sb.toString());
+
+        sb.append((StrBuilder) null, 0, 1);
+        assertEquals("foo", sb.toString());
+
+        try {
+            sb.append(new StrBuilder("bar"), -1, 1);
+            fail("append(char[], -1,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), 3, 1);
+            fail("append(char[], 3,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), 1, -1);
+            fail("append(char[],, -1) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), 1, 3);
+            fail("append(char[], 1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), -1, 3);
+            fail("append(char[], -1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), 4, 0);
+            fail("append(char[], 4, 0) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.append(new StrBuilder("bar"), 3, 0);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StrBuilder("abcbardef"), 3, 3);
+        assertEquals("foobar", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_CharArray() {
+        StrBuilder sb = new StrBuilder();
+        
+        sb.append((char[]) null);
+        assertEquals("", sb.toString());
+
+        sb.append(new char[0]);
+        assertEquals("", sb.toString());
+
+        sb.append(new char[]{'f', 'o', 'o'});
+        assertEquals("foo", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_CharArray_int_int() {
+        StrBuilder sb = new StrBuilder();
+        
+        sb.append(new char[]{'f', 'o', 'o'}, 0, 3);
+        assertEquals("foo", sb.toString());
+
+        sb.append((char[]) null, 0, 1);
+        assertEquals("foo", sb.toString());
+
+        try {
+            sb.append(new char[]{'b', 'a', 'r'}, -1, 1);
+            fail("append(char[], -1,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new char[]{'b', 'a', 'r'}, 3, 1);
+            fail("append(char[], 3,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new char[]{'b', 'a', 'r'}, 1, -1);
+            fail("append(char[],, -1) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new char[]{'b', 'a', 'r'}, 1, 3);
+            fail("append(char[], 1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new char[]{'b', 'a', 'r'}, -1, 3);
+            fail("append(char[], -1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new char[]{'b', 'a', 'r'}, 4, 0);
+            fail("append(char[], 4, 0) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.append(new char[]{'b', 'a', 'r'}, 3, 0);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new char[]{'a', 'b', 'c', 'b', 'a', 'r', 'd', 'e', 'f'}, 3, 3);
+        assertEquals("foobar", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_Primitive() {
+        StrBuilder sb = new StrBuilder();
+        sb.append(true);
+        assertEquals("true", sb.toString());
+
+        sb.append(false);
+        assertEquals("truefalse", sb.toString());
+
+        sb.append('!');
+        assertEquals("truefalse!", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppend_PrimitiveNumber() {
+        StrBuilder sb = new StrBuilder();
+        sb.append(0);
+        assertEquals("0", sb.toString());
+
+        sb.append(1L);
+        assertEquals("01", sb.toString());
+
+        sb.append(2.3f);
+        assertEquals("012.3", sb.toString());
+
+        sb.append(4.5d);
+        assertEquals("012.34.5", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendPadding() {
+        StrBuilder sb = new StrBuilder();
+        sb.append("foo");
+        assertEquals("foo", sb.toString());
+
+        sb.appendPadding(-1, '-');
+        assertEquals("foo", sb.toString());
+
+        sb.appendPadding(0, '-');
+        assertEquals("foo", sb.toString());
+
+        sb.appendPadding(1, '-');
+        assertEquals("foo-", sb.toString());
+
+        sb.appendPadding(16, '-');
+        assertEquals(20, sb.length());
+        //            12345678901234567890
+        assertEquals("foo-----------------", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendFixedWidthPadLeft() {
+        StrBuilder sb = new StrBuilder();
+        sb.appendFixedWidthPadLeft("foo", -1, '-');
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft("foo", 0, '-');
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft("foo", 1, '-');
+        assertEquals("o", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft("foo", 2, '-');
+        assertEquals("oo", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft("foo", 3, '-');
+        assertEquals("foo", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft("foo", 4, '-');
+        assertEquals("-foo", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft("foo", 10, '-');
+        assertEquals(10, sb.length());
+        //            1234567890
+        assertEquals("-------foo", sb.toString());
+
+        sb.clear();
+        sb.setNullText("null");
+        sb.appendFixedWidthPadLeft(null, 5, '-');
+        assertEquals("-null", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendFixedWidthPadLeft_int() {
+        StrBuilder sb = new StrBuilder();
+        sb.appendFixedWidthPadLeft(123, -1, '-');
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft(123, 0, '-');
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft(123, 1, '-');
+        assertEquals("3", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft(123, 2, '-');
+        assertEquals("23", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft(123, 3, '-');
+        assertEquals("123", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft(123, 4, '-');
+        assertEquals("-123", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadLeft(123, 10, '-');
+        assertEquals(10, sb.length());
+        //            1234567890
+        assertEquals("-------123", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendFixedWidthPadRight() {
+        StrBuilder sb = new StrBuilder();
+        sb.appendFixedWidthPadRight("foo", -1, '-');
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight("foo", 0, '-');
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight("foo", 1, '-');
+        assertEquals("f", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight("foo", 2, '-');
+        assertEquals("fo", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight("foo", 3, '-');
+        assertEquals("foo", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight("foo", 4, '-');
+        assertEquals("foo-", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight("foo", 10, '-');
+        assertEquals(10, sb.length());
+        //            1234567890
+        assertEquals("foo-------", sb.toString());
+
+        sb.clear();
+        sb.setNullText("null");
+        sb.appendFixedWidthPadRight(null, 5, '-');
+        assertEquals("null-", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendFixedWidthPadRight_int() {
+        StrBuilder sb = new StrBuilder();
+        sb.appendFixedWidthPadRight(123, -1, '-');
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight(123, 0, '-');
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight(123, 1, '-');
+        assertEquals("1", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight(123, 2, '-');
+        assertEquals("12", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight(123, 3, '-');
+        assertEquals("123", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight(123, 4, '-');
+        assertEquals("123-", sb.toString());
+
+        sb.clear();
+        sb.appendFixedWidthPadRight(123, 10, '-');
+        assertEquals(10, sb.length());
+        //            1234567890
+        assertEquals("123-------", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendWithSeparators_Array() {
+        StrBuilder sb = new StrBuilder();
+        sb.appendWithSeparators((Object[]) null, ",");
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(new Object[0], ",");
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(new Object[]{"foo", "bar", "baz"}, ",");
+        assertEquals("foo,bar,baz", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(new Object[]{"foo", "bar", "baz"}, null);
+        assertEquals("foobarbaz", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(new Object[]{"foo", null, "baz"}, ",");
+        assertEquals("foo,,baz", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendWithSeparators_Collection() {
+        StrBuilder sb = new StrBuilder();
+        sb.appendWithSeparators((Collection) null, ",");
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(Collections.EMPTY_LIST, ",");
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(Arrays.asList(new Object[]{"foo", "bar", "baz"}), ",");
+        assertEquals("foo,bar,baz", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(Arrays.asList(new Object[]{"foo", "bar", "baz"}), null);
+        assertEquals("foobarbaz", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(Arrays.asList(new Object[]{"foo", null, "baz"}), ",");
+        assertEquals("foo,,baz", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendWithSeparators_Iterator() {
+        StrBuilder sb = new StrBuilder();
+        sb.appendWithSeparators((Iterator) null, ",");
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(Collections.EMPTY_LIST.iterator(), ",");
+        assertEquals("", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(Arrays.asList(new Object[]{"foo", "bar", "baz"}).iterator(), ",");
+        assertEquals("foo,bar,baz", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(Arrays.asList(new Object[]{"foo", "bar", "baz"}).iterator(), null);
+        assertEquals("foobarbaz", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(Arrays.asList(new Object[]{"foo", null, "baz"}).iterator(), ",");
+        assertEquals("foo,,baz", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testAppendWithSeparatorsWithNullText() {
+        StrBuilder sb = new StrBuilder();
+        sb.setNullText("null");
+        sb.appendWithSeparators(new Object[]{"foo", null, "baz"}, ",");
+        assertEquals("foo,null,baz", sb.toString());
+
+        sb.clear();
+        sb.appendWithSeparators(Arrays.asList(new Object[]{"foo", null, "baz"}), ",");
+        assertEquals("foo,null,baz", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testInsert() {
+
+        StrBuilder sb = new StrBuilder();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, FOO);
+            fail("insert(-1, Object) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, FOO);
+            fail("insert(7, Object) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, (Object) null);
+        assertEquals("barbaz", sb.toString());
+
+        sb.insert(0, FOO);
+        assertEquals("foobarbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, "foo");
+            fail("insert(-1, String) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, "foo");
+            fail("insert(7, String) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, (String) null);
+        assertEquals("barbaz", sb.toString());
+
+        sb.insert(0, "foo");
+        assertEquals("foobarbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, new char[]{'f', 'o', 'o'});
+            fail("insert(-1, char[]) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, new char[]{'f', 'o', 'o'});
+            fail("insert(7, char[]) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, (char[]) null);
+        assertEquals("barbaz", sb.toString());
+
+        sb.insert(0, new char[0]);
+        assertEquals("barbaz", sb.toString());
+
+        sb.insert(0, new char[]{'f', 'o', 'o'});
+        assertEquals("foobarbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, new char[]{'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 3, 3);
+            fail("insert(-1, char[], 3, 3) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, new char[]{'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 3, 3);
+            fail("insert(7, char[], 3, 3) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, (char[]) null, 0, 0);
+        assertEquals("barbaz", sb.toString());
+
+        sb.insert(0, new char[0], 0, 0);
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(0, new char[]{'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, -1, 3);
+            fail("insert(0, char[], -1, 3) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(0, new char[]{'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 10, 3);
+            fail("insert(0, char[], 10, 3) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(0, new char[]{'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 0, -1);
+            fail("insert(0, char[], 0, -1) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(0, new char[]{'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 0, 10);
+            fail("insert(0, char[], 0, 10) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, new char[]{'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 0, 0);
+        assertEquals("barbaz", sb.toString());
+
+        sb.insert(0, new char[]{'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 3, 3);
+        assertEquals("foobarbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, true);
+            fail("insert(-1, boolean) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, true);
+            fail("insert(7, boolean) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, true);
+        assertEquals("truebarbaz", sb.toString());
+
+        sb.insert(0, false);
+        assertEquals("falsetruebarbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, '!');
+            fail("insert(-1, char) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, '!');
+            fail("insert(7, char) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, '!');
+        assertEquals("!barbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, 0);
+            fail("insert(-1, int) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, 0);
+            fail("insert(7, int) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, '0');
+        assertEquals("0barbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, 1L);
+            fail("insert(-1, long) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, 1L);
+            fail("insert(7, long) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, 1L);
+        assertEquals("1barbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, 2.3F);
+            fail("insert(-1, float) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, 2.3F);
+            fail("insert(7, float) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, 2.3F);
+        assertEquals("2.3barbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, 4.5D);
+            fail("insert(-1, double) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, 4.5D);
+            fail("insert(7, double) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, 4.5D);
+        assertEquals("4.5barbaz", sb.toString());
+    }
+
+    //-----------------------------------------------------------------------
+    public void testInsertWithNullText() {
+        StrBuilder sb = new StrBuilder();
+        sb.setNullText("null");
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, FOO);
+            fail("insert(-1, Object) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, FOO);
+            fail("insert(7, Object) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, (Object) null);
+        assertEquals("nullbarbaz", sb.toString());
+
+        sb.insert(0, FOO);
+        assertEquals("foonullbarbaz", sb.toString());
+
+        sb.clear();
+        sb.append("barbaz");
+        assertEquals("barbaz", sb.toString());
+
+        try {
+            sb.insert(-1, "foo");
+            fail("insert(-1, String) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.insert(7, "foo");
+            fail("insert(7, String) expected StringIndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.insert(0, (String) null);
+        assertEquals("nullbarbaz", sb.toString());
+
+        sb.insert(0, "foo");
+        assertEquals("foonullbarbaz", sb.toString());
+    }
+
+}

Propchange: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderAppendInsertTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/text/StrBuilderAppendInsertTest.java
------------------------------------------------------------------------------
    svn:keywords = "author date id revision"



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message