Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 37171 invoked from network); 14 Aug 2005 21:46:20 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 14 Aug 2005 21:46:20 -0000 Received: (qmail 46091 invoked by uid 500); 14 Aug 2005 21:46:08 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 45941 invoked by uid 500); 14 Aug 2005 21:46:06 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 45353 invoked by uid 500); 14 Aug 2005 21:46:03 -0000 Received: (qmail 45329 invoked by uid 99); 14 Aug 2005 21:46:03 -0000 X-ASF-Spam-Status: No, hits=-9.8 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Sun, 14 Aug 2005 14:46:01 -0700 Received: (qmail 36906 invoked by uid 65534); 14 Aug 2005 21:46:01 -0000 Message-ID: <20050814214601.36904.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commons-cvs@jakarta.apache.org From: scolebourne@apache.org X-Mailer: svnmailer-1.0.3 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * This method is called to check for a match. + * The parameter pos represents the current position to be + * checked in the string buffer (a character array which must + * not be changed). + * The API guarantees that pos is a valid index for buffer. + *

+ * 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. + *

+ * The matching code may check one character or many. + * It may check characters preceeding pos as well as those + * after, so long as no checks exceed the bounds specified. + *

+ * 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 NoMatcher. + */ + NoMatcher() { + super(); + } + + /** + * Always returns false. + * + * @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 TrimMatcher. + */ + 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