From 05afb9f1ddaf432a86aab24b097c9f121bd056d1 Mon Sep 17 00:00:00 2001
From: Pete Royle null
safe.
The StringUtils
class defines certain words related to
+ * String handling.
null
""
)' '
, char 32)StringUtils
handles null
input Strings quietly.
+ * That is to say that a null
input will return null
.
+ * Where a boolean
or int
is being returned
+ * details vary by method.
A side effect of the null
handling is that a
+ * NullPointerException
should be considered a bug in
+ * StringUtils
(except for deprecated methods).
Methods in this class give sample code to explain their operation.
+ * The symbol *
is used to indicate any input including null
.
""
.
+ * @since 2.0
+ */
+ public static final String EMPTY = "";
+
+ /**
+ * Represents a failed index search.
+ * @since 2.1
+ */
+ public static final int INDEX_NOT_FOUND = -1;
+
+ /**
+ * The maximum size to which the padding constant(s) can expand.
+ */ + private static final int PAD_LIMIT = 8192; + + /** + *StringUtils
instances should NOT be constructed in
+ * standard programming. Instead, the class should be used as
+ * StringUtils.trim(" foo ");
.
This constructor is public to permit tools that require a JavaBean + * instance to operate.
+ */ + public StringUtils() { + super(); + } + + // Case conversion + //----------------------------------------------------------------------- + /** + *Converts a String to upper case as per {@link String#toUpperCase()}.
+ * + *A null
input String returns null
.
+ * StringUtils.upperCase(null) = null + * StringUtils.upperCase("") = "" + * StringUtils.upperCase("aBc") = "ABC" + *+ * + * @param str the String to upper case, may be null + * @return the upper cased String,
null
if null String input
+ */
+ public static String upperCase(String str) {
+ if (str == null) {
+ return null;
+ }
+ return str.toUpperCase();
+ }
+
+ /**
+ * Converts a String to lower case as per {@link String#toLowerCase()}.
+ * + *A null
input String returns null
.
+ * StringUtils.lowerCase(null) = null + * StringUtils.lowerCase("") = "" + * StringUtils.lowerCase("aBc") = "abc" + *+ * + * @param str the String to lower case, may be null + * @return the lower cased String,
null
if null String input
+ */
+ public static String lowerCase(String str) {
+ if (str == null) {
+ return null;
+ }
+ return str.toLowerCase();
+ }
+
+ // Empty checks
+ //-----------------------------------------------------------------------
+ /**
+ * Checks if a String is empty ("") or null.
+ * + *+ * StringUtils.isEmpty(null) = true + * StringUtils.isEmpty("") = true + * StringUtils.isEmpty(" ") = false + * StringUtils.isEmpty("bob") = false + * StringUtils.isEmpty(" bob ") = false + *+ * + *
NOTE: This method changed in Lang version 2.0. + * It no longer trims the String. + * That functionality is available in isBlank().
+ * + * @param str the String to check, may be null + * @returntrue
if the String is empty or null
+ */
+ private static boolean isEmpty(String str) {
+ return str == null || str.length() == 0;
+ }
+
+ /**
+ * Removes control characters (char <= 32) from both
+ * ends of this String, handling null
by returning
+ * null
.
The String is trimmed using {@link String#trim()}. + * Trim removes start and end characters <= 32. + * To strip whitespace use {@link #strip(String)}.
+ * + *To trim your choice of characters, use the + * {@link #strip(String, String)} methods.
+ * + *+ * StringUtils.trim(null) = null + * StringUtils.trim("") = "" + * StringUtils.trim(" ") = "" + * StringUtils.trim("abc") = "abc" + * StringUtils.trim(" abc ") = "abc" + *+ * + * @param str the String to be trimmed, may be null + * @return the trimmed string,
null
if null String input
+ */
+ public static String trim(String str) {
+ return str == null ? null : str.trim();
+ }
+
+ /**
+ /**
+ /**
+ /**
+ // Splitting
+ //-----------------------------------------------------------------------
+ /**
+ * Splits the provided text into an array, using whitespace as the + * separator. + * Whitespace is defined by {@link Character#isWhitespace(char)}.
+ * + *The separator is not included in the returned String array. + * Adjacent separators are treated as one separator. + * For more control over the split use the StrTokenizer class.
+ * + *A null
input String returns null
.
+ * StringUtils.split(null) = null + * StringUtils.split("") = [] + * StringUtils.split("abc def") = ["abc", "def"] + * StringUtils.split("abc def") = ["abc", "def"] + * StringUtils.split(" abc ") = ["abc"] + *+ * + * @param str the String to parse, may be null + * @return an array of parsed Strings,
null
if null String input
+ */
+ public static String[] split(String str) {
+ return split(str, null, -1);
+ }
+
+ /**
+ * Splits the provided text into an array, separators specified. + * This is an alternative to using StringTokenizer.
+ * + *The separator is not included in the returned String array. + * Adjacent separators are treated as one separator. + * For more control over the split use the StrTokenizer class.
+ * + *A null
input String returns null
.
+ * A null
separatorChars splits on whitespace.
+ * StringUtils.split(null, *) = null + * StringUtils.split("", *) = [] + * StringUtils.split("abc def", null) = ["abc", "def"] + * StringUtils.split("abc def", " ") = ["abc", "def"] + * StringUtils.split("abc def", " ") = ["abc", "def"] + * StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"] + *+ * + * @param str the String to parse, may be null + * @param separatorChars the characters used as the delimiters, + *
null
splits on whitespace
+ * @return an array of parsed Strings, null
if null String input
+ */
+ public static String[] split(String str, String separatorChars) {
+ return splitWorker(str, separatorChars, -1, false);
+ }
+
+ /**
+ * Splits the provided text into an array with a maximum length, + * separators specified.
+ * + *The separator is not included in the returned String array. + * Adjacent separators are treated as one separator.
+ * + *A null
input String returns null
.
+ * A null
separatorChars splits on whitespace.
If more than max
delimited substrings are found, the last
+ * returned string includes all characters after the first max - 1
+ * returned strings (including separator characters).
+ * StringUtils.split(null, *, *) = null + * StringUtils.split("", *, *) = [] + * StringUtils.split("ab de fg", null, 0) = ["ab", "cd", "ef"] + * StringUtils.split("ab de fg", null, 0) = ["ab", "cd", "ef"] + * StringUtils.split("ab:cd:ef", ":", 0) = ["ab", "cd", "ef"] + * StringUtils.split("ab:cd:ef", ":", 2) = ["ab", "cd:ef"] + *+ * + * @param str the String to parse, may be null + * @param separatorChars the characters used as the delimiters, + *
null
splits on whitespace
+ * @param max the maximum number of elements to include in the
+ * array. A zero or negative value implies no limit
+ * @return an array of parsed Strings, null
if null String input
+ */
+ private static String[] split(String str, String separatorChars, int max) {
+ return splitWorker(str, separatorChars, max, false);
+ }
+
+ /**
+ * Performs the logic for the split
and
+ * splitPreserveAllTokens
methods that return a maximum array
+ * length.
+ *
+ * @param str the String to parse, may be null
+ * @param separatorChars the separate character
+ * @param max the maximum number of elements to include in the
+ * array. A zero or negative value implies no limit.
+ * @param preserveAllTokens if true
, adjacent separators are
+ * treated as empty token separators; if false
, adjacent
+ * separators are treated as one separator.
+ * @return an array of parsed Strings, null
if null String input
+ */
+ private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {
+ // Performance tuned for 2.0 (JDK1.4)
+ // Direct code is quicker than StringTokenizer.
+ // Also, StringTokenizer uses isSpace() not isWhitespace()
+
+ if (str == null) {
+ return null;
+ }
+ int len = str.length();
+ if (len == 0) {
+ return EMPTY_STRING_ARRAY;
+ }
+ List list = new ArrayList();
+ int sizePlus1 = 1;
+ int i = 0, start = 0;
+ boolean match = false;
+ boolean lastMatch = false;
+ if (separatorChars == null) {
+ // Null separator means use whitespace
+ while (i < len) {
+ if (Character.isWhitespace(str.charAt(i))) {
+ if (match || preserveAllTokens) {
+ lastMatch = true;
+ if (sizePlus1++ == max) {
+ i = len;
+ lastMatch = false;
+ }
+ list.add(str.substring(start, i));
+ match = false;
+ }
+ start = ++i;
+ continue;
+ }
+ lastMatch = false;
+ match = true;
+ i++;
+ }
+ } else if (separatorChars.length() == 1) {
+ // Optimise 1 character case
+ char sep = separatorChars.charAt(0);
+ while (i < len) {
+ if (str.charAt(i) == sep) {
+ if (match || preserveAllTokens) {
+ lastMatch = true;
+ if (sizePlus1++ == max) {
+ i = len;
+ lastMatch = false;
+ }
+ list.add(str.substring(start, i));
+ match = false;
+ }
+ start = ++i;
+ continue;
+ }
+ lastMatch = false;
+ match = true;
+ i++;
+ }
+ } else {
+ // standard case
+ while (i < len) {
+ if (separatorChars.indexOf(str.charAt(i)) >= 0) {
+ if (match || preserveAllTokens) {
+ lastMatch = true;
+ if (sizePlus1++ == max) {
+ i = len;
+ lastMatch = false;
+ }
+ list.add(str.substring(start, i));
+ match = false;
+ }
+ start = ++i;
+ continue;
+ }
+ lastMatch = false;
+ match = true;
+ i++;
+ }
+ }
+ if (match || (preserveAllTokens && lastMatch)) {
+ list.add(str.substring(start, i));
+ }
+ return (String[]) list.toArray(new String[list.size()]);
+ }
+
+ /**
+ * Joins the elements of the provided array into a single String + * containing the provided list of elements.
+ * + *No delimiter is added before or after the list.
+ * A null
separator is the same as an empty String ("").
+ * Null objects or empty strings within the array are represented by
+ * empty strings.
+ * StringUtils.join(null, *) = null + * StringUtils.join([], *) = "" + * StringUtils.join([null], *) = "" + * StringUtils.join(["a", "b", "c"], "--") = "a--b--c" + * StringUtils.join(["a", "b", "c"], null) = "abc" + * StringUtils.join(["a", "b", "c"], "") = "abc" + * StringUtils.join([null, "", "a"], ',') = ",,a" + *+ * + * @param array the array of values to join together, may be null + * @param separator the separator character to use, null treated as "" + * @return the joined String,
null
if null array input
+ */
+ public static String join(Object[] array, String separator) {
+ if (array == null) {
+ return null;
+ }
+ return join(array, separator, 0, array.length);
+ }
+
+ /**
+ * Joins the elements of the provided array into a single String + * containing the provided list of elements.
+ * + *No delimiter is added before or after the list.
+ * A null
separator is the same as an empty String ("").
+ * Null objects or empty strings within the array are represented by
+ * empty strings.
+ * StringUtils.join(null, *) = null + * StringUtils.join([], *) = "" + * StringUtils.join([null], *) = "" + * StringUtils.join(["a", "b", "c"], "--") = "a--b--c" + * StringUtils.join(["a", "b", "c"], null) = "abc" + * StringUtils.join(["a", "b", "c"], "") = "abc" + * StringUtils.join([null, "", "a"], ',') = ",,a" + *+ * + * @param array the array of values to join together, may be null + * @param separator the separator character to use, null treated as "" + * @param startIndex the first index to start joining from. It is + * an error to pass in an end index past the end of the array + * @param endIndex the index to stop joining from (exclusive). It is + * an error to pass in an end index past the end of the array + * @return the joined String,
null
if null array input
+ */
+ private static String join(Object[] array, String separator, int startIndex, int endIndex) {
+ if (array == null) {
+ return null;
+ }
+ if (separator == null) {
+ separator = EMPTY;
+ }
+
+ // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator))
+ // (Assuming that all Strings are roughly equally long)
+ int bufSize = (endIndex - startIndex);
+ if (bufSize <= 0) {
+ return EMPTY;
+ }
+
+ bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length())
+ + separator.length());
+
+ StringBuffer buf = new StringBuffer(bufSize);
+
+ for (int i = startIndex; i < endIndex; i++) {
+ if (i > startIndex) {
+ buf.append(separator);
+ }
+ if (array[i] != null) {
+ buf.append(array[i]);
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Replaces all occurrences of a String within another String.
+ * + *A null
reference passed to this method is a no-op.
+ * StringUtils.replace(null, *, *) = null + * StringUtils.replace("", *, *) = "" + * StringUtils.replace("any", null, *) = "any" + * StringUtils.replace("any", *, null) = "any" + * StringUtils.replace("any", "", *) = "any" + * StringUtils.replace("aba", "a", null) = "aba" + * StringUtils.replace("aba", "a", "") = "b" + * StringUtils.replace("aba", "a", "z") = "zbz" + *+ * + * @see #replace(String text, String searchString, String replacement, int max) + * @param text text to search and replace in, may be null + * @param searchString the String to search for, may be null + * @param replacement the String to replace it with, may be null + * @return the text with any replacements processed, + *
null
if null String input
+ */
+ public static String replace(String text, String searchString, String replacement) {
+ return replace(text, searchString, replacement, -1);
+ }
+
+ /**
+ * Replaces a String with another String inside a larger String,
+ * for the first max
values of the search String.
A null
reference passed to this method is a no-op.
+ * StringUtils.replace(null, *, *, *) = null + * StringUtils.replace("", *, *, *) = "" + * StringUtils.replace("any", null, *, *) = "any" + * StringUtils.replace("any", *, null, *) = "any" + * StringUtils.replace("any", "", *, *) = "any" + * StringUtils.replace("any", *, *, 0) = "any" + * StringUtils.replace("abaa", "a", null, -1) = "abaa" + * StringUtils.replace("abaa", "a", "", -1) = "b" + * StringUtils.replace("abaa", "a", "z", 0) = "abaa" + * StringUtils.replace("abaa", "a", "z", 1) = "zbaa" + * StringUtils.replace("abaa", "a", "z", 2) = "zbza" + * StringUtils.replace("abaa", "a", "z", -1) = "zbzz" + *+ * + * @param text text to search and replace in, may be null + * @param searchString the String to search for, may be null + * @param replacement the String to replace it with, may be null + * @param max maximum number of values to replace, or
-1
if no maximum
+ * @return the text with any replacements processed,
+ * null
if null String input
+ */
+ private static String replace(String text, String searchString, String replacement, int max) {
+ if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
+ return text;
+ }
+ int start = 0;
+ int end = text.indexOf(searchString, start);
+ if (end == -1) {
+ return text;
+ }
+ int replLength = searchString.length();
+ int increase = replacement.length() - replLength;
+ increase = (increase < 0 ? 0 : increase);
+ increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
+ StringBuffer buf = new StringBuffer(text.length() + increase);
+ while (end != -1) {
+ buf.append(text.substring(start, end)).append(replacement);
+ start = end + replLength;
+ if (--max == 0) {
+ break;
+ }
+ end = text.indexOf(searchString, start);
+ }
+ buf.append(text.substring(start));
+ return buf.toString();
+ }
+
+ /**
+ * Returns padding using the specified delimiter repeated + * to a given length.
+ * + *+ * StringUtils.padding(0, 'e') = "" + * StringUtils.padding(3, 'e') = "eee" + * StringUtils.padding(-2, 'e') = IndexOutOfBoundsException + *+ * + *
Note: this method doesn't not support padding with
+ * Unicode Supplementary Characters
+ * as they require a pair of char
s to be represented.
+ * If you are needing to support full I18N of your applications
+ * consider using {@link #repeat(String, int)} instead.
+ *
repeat < 0
+ * @see #repeat(String, int)
+ */
+ private static String padding(int repeat, char padChar) throws IndexOutOfBoundsException {
+ if (repeat < 0) {
+ throw new IndexOutOfBoundsException("Cannot pad a negative amount: " + repeat);
+ }
+ final char[] buf = new char[repeat];
+ for (int i = 0; i < buf.length; i++) {
+ buf[i] = padChar;
+ }
+ return new String(buf);
+ }
+
+ /**
+ * Right pad a String with spaces (' ').
+ * + *The String is padded to the size of size
.
+ * StringUtils.rightPad(null, *) = null + * StringUtils.rightPad("", 3) = " " + * StringUtils.rightPad("bat", 3) = "bat" + * StringUtils.rightPad("bat", 5) = "bat " + * StringUtils.rightPad("bat", 1) = "bat" + * StringUtils.rightPad("bat", -1) = "bat" + *+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @return right padded String or original String if no padding is necessary, + *
null
if null String input
+ */
+ public static String rightPad(String str, int size) {
+ return rightPad(str, size, " ");
+ }
+
+
+ /**
+ * Right pad a String with a specified character.
+ * + *The String is padded to the size of size
.
+ * StringUtils.rightPad(null, *, *) = null + * StringUtils.rightPad("", 3, 'z') = "zzz" + * StringUtils.rightPad("bat", 3, 'z') = "bat" + * StringUtils.rightPad("bat", 5, 'z') = "batzz" + * StringUtils.rightPad("bat", 1, 'z') = "bat" + * StringUtils.rightPad("bat", -1, 'z') = "bat" + *+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @param padChar the character to pad with + * @return right padded String or original String if no padding is necessary, + *
null
if null String input
+ * @since 2.0
+ */
+ private static String rightPad(String str, int size, char padChar) {
+ if (str == null) {
+ return null;
+ }
+ int pads = size - str.length();
+ if (pads <= 0) {
+ return str; // returns original String when possible
+ }
+ if (pads > PAD_LIMIT) {
+ return rightPad(str, size, String.valueOf(padChar));
+ }
+ return str.concat(padding(pads, padChar));
+ }
+
+ /**
+ * Right pad a String with a specified String.
+ * + *The String is padded to the size of size
.
+ * StringUtils.rightPad(null, *, *) = null + * StringUtils.rightPad("", 3, "z") = "zzz" + * StringUtils.rightPad("bat", 3, "yz") = "bat" + * StringUtils.rightPad("bat", 5, "yz") = "batyz" + * StringUtils.rightPad("bat", 8, "yz") = "batyzyzy" + * StringUtils.rightPad("bat", 1, "yz") = "bat" + * StringUtils.rightPad("bat", -1, "yz") = "bat" + * StringUtils.rightPad("bat", 5, null) = "bat " + * StringUtils.rightPad("bat", 5, "") = "bat " + *+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @param padStr the String to pad with, null or empty treated as single space + * @return right padded String or original String if no padding is necessary, + *
null
if null String input
+ */
+ public static String rightPad(String str, int size, String padStr) {
+ if (str == null) {
+ return null;
+ }
+ if (isEmpty(padStr)) {
+ padStr = " ";
+ }
+ int padLen = padStr.length();
+ int strLen = str.length();
+ int pads = size - strLen;
+ if (pads <= 0) {
+ return str; // returns original String when possible
+ }
+ if (padLen == 1 && pads <= PAD_LIMIT) {
+ return rightPad(str, size, padStr.charAt(0));
+ }
+
+ if (pads == padLen) {
+ return str.concat(padStr);
+ } else if (pads < padLen) {
+ return str.concat(padStr.substring(0, pads));
+ } else {
+ char[] padding = new char[pads];
+ char[] padChars = padStr.toCharArray();
+ for (int i = 0; i < pads; i++) {
+ padding[i] = padChars[i % padLen];
+ }
+ return str.concat(new String(padding));
+ }
+ }
+
+ /**
+ * Left pad a String with spaces (' ').
+ * + *The String is padded to the size of size
.
+ * StringUtils.leftPad(null, *) = null + * StringUtils.leftPad("", 3) = " " + * StringUtils.leftPad("bat", 3) = "bat" + * StringUtils.leftPad("bat", 5) = " bat" + * StringUtils.leftPad("bat", 1) = "bat" + * StringUtils.leftPad("bat", -1) = "bat" + *+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @return left padded String or original String if no padding is necessary, + *
null
if null String input
+ */
+ public static String leftPad(String str, int size) {
+ return leftPad(str, size, " ");
+ }
+
+
+ /**
+ * Left pad a String with a specified character.
+ * + *Pad to a size of size
.
+ * StringUtils.leftPad(null, *, *) = null + * StringUtils.leftPad("", 3, 'z') = "zzz" + * StringUtils.leftPad("bat", 3, 'z') = "bat" + * StringUtils.leftPad("bat", 5, 'z') = "zzbat" + * StringUtils.leftPad("bat", 1, 'z') = "bat" + * StringUtils.leftPad("bat", -1, 'z') = "bat" + *+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @param padChar the character to pad with + * @return left padded String or original String if no padding is necessary, + *
null
if null String input
+ * @since 2.0
+ */
+ private static String leftPad(String str, int size, char padChar) {
+ if (str == null) {
+ return null;
+ }
+ int pads = size - str.length();
+ if (pads <= 0) {
+ return str; // returns original String when possible
+ }
+ if (pads > PAD_LIMIT) {
+ return leftPad(str, size, String.valueOf(padChar));
+ }
+ return padding(pads, padChar).concat(str);
+ }
+
+ /**
+ * Left pad a String with a specified String.
+ * + *Pad to a size of size
.
+ * StringUtils.leftPad(null, *, *) = null + * StringUtils.leftPad("", 3, "z") = "zzz" + * StringUtils.leftPad("bat", 3, "yz") = "bat" + * StringUtils.leftPad("bat", 5, "yz") = "yzbat" + * StringUtils.leftPad("bat", 8, "yz") = "yzyzybat" + * StringUtils.leftPad("bat", 1, "yz") = "bat" + * StringUtils.leftPad("bat", -1, "yz") = "bat" + * StringUtils.leftPad("bat", 5, null) = " bat" + * StringUtils.leftPad("bat", 5, "") = " bat" + *+ * + * @param str the String to pad out, may be null + * @param size the size to pad to + * @param padStr the String to pad with, null or empty treated as single space + * @return left padded String or original String if no padding is necessary, + *
null
if null String input
+ */
+ public static String leftPad(String str, int size, String padStr) {
+ if (str == null) {
+ return null;
+ }
+ if (isEmpty(padStr)) {
+ padStr = " ";
+ }
+ int padLen = padStr.length();
+ int strLen = str.length();
+ int pads = size - strLen;
+ if (pads <= 0) {
+ return str; // returns original String when possible
+ }
+ if (padLen == 1 && pads <= PAD_LIMIT) {
+ return leftPad(str, size, padStr.charAt(0));
+ }
+
+ if (pads == padLen) {
+ return padStr.concat(str);
+ } else if (pads < padLen) {
+ return padStr.substring(0, pads).concat(str);
+ } else {
+ char[] padding = new char[pads];
+ char[] padChars = padStr.toCharArray();
+ for (int i = 0; i < pads; i++) {
+ padding[i] = padChars[i % padLen];
+ }
+ return new String(padding).concat(str);
+ }
+ }
+
+ // Centering
+ //-----------------------------------------------------------------------
+ /**
+ * Centers a String in a larger String of size size
+ * using the space character (' ').
+ * + *
If the size is less than the String length, the String is returned.
+ * A null
String returns null
.
+ * A negative size is treated as zero.
Equivalent to center(str, size, " ")
.
+ * StringUtils.center(null, *) = null + * StringUtils.center("", 4) = " " + * StringUtils.center("ab", -1) = "ab" + * StringUtils.center("ab", 4) = " ab " + * StringUtils.center("abcd", 2) = "abcd" + * StringUtils.center("a", 4) = " a " + *+ * + * @param str the String to center, may be null + * @param size the int size of new String, negative treated as zero + * @return centered String,
null
if null String input
+ */
+ public static String center(String str, int size) {
+ return center(str, size, " ");
+ }
+
+ /**
+ * Centers a String in a larger String of size size
.
+ * Uses a supplied String as the value to pad the String with.
If the size is less than the String length, the String is returned.
+ * A null
String returns null
.
+ * A negative size is treated as zero.
+ * StringUtils.center(null, *, *) = null + * StringUtils.center("", 4, " ") = " " + * StringUtils.center("ab", -1, " ") = "ab" + * StringUtils.center("ab", 4, " ") = " ab" + * StringUtils.center("abcd", 2, " ") = "abcd" + * StringUtils.center("a", 4, " ") = " a " + * StringUtils.center("a", 4, "yz") = "yayz" + * StringUtils.center("abc", 7, null) = " abc " + * StringUtils.center("abc", 7, "") = " abc " + *+ * + * @param str the String to center, may be null + * @param size the int size of new String, negative treated as zero + * @param padStr the String to pad the new String with, must not be null or empty + * @return centered String,
null
if null String input
+ * @throws IllegalArgumentException if padStr is null
or empty
+ */
+ public static String center(String str, int size, String padStr) {
+ if (str == null || size <= 0) {
+ return str;
+ }
+ if (isEmpty(padStr)) {
+ padStr = " ";
+ }
+ int strLen = str.length();
+ int pads = size - strLen;
+ if (pads <= 0) {
+ return str;
+ }
+ str = leftPad(str, strLen + pads / 2, padStr);
+ str = rightPad(str, size, padStr);
+ return str;
+ }
+
+ /**
+ * Capitalizes a String changing the first letter to title case as + * per {@link Character#toTitleCase(char)}. No other letters are changed.
+ * + *For a word based algorithm, see {@link WordUtils#capitalize(String)}.
+ * A null
input String returns null
.
+ * StringUtils.capitalize(null) = null + * StringUtils.capitalize("") = "" + * StringUtils.capitalize("cat") = "Cat" + * StringUtils.capitalize("cAt") = "CAt" + *+ * + * @param str the String to capitalize, may be null + * @return the capitalized String,
null
if null String input
+ * @see WordUtils#capitalize(String)
+ * @see #uncapitalize(String)
+ * @since 2.0
+ */
+ public static String capitalize(String str) {
+ int strLen;
+ if (str == null || (strLen = str.length()) == 0) {
+ return str;
+ }
+ return new StringBuffer(strLen)
+ .append(Character.toTitleCase(str.charAt(0)))
+ .append(str.substring(1))
+ .toString();
+ }
+
+ /**
+ * Uncapitalizes a String changing the first letter to title case as + * per {@link Character#toLowerCase(char)}. No other letters are changed.
+ * + *For a word based algorithm, see {@link WordUtils#uncapitalize(String)}.
+ * A null
input String returns null
.
+ * StringUtils.uncapitalize(null) = null + * StringUtils.uncapitalize("") = "" + * StringUtils.uncapitalize("Cat") = "cat" + * StringUtils.uncapitalize("CAT") = "cAT" + *+ * + * @param str the String to uncapitalize, may be null + * @return the uncapitalized String,
null
if null String input
+ * @see WordUtils#uncapitalize(String)
+ * @see #capitalize(String)
+ * @since 2.0
+ */
+ public static String uncapitalize(String str) {
+ int strLen;
+ if (str == null || (strLen = str.length()) == 0) {
+ return str;
+ }
+ return new StringBuffer(strLen)
+ .append(Character.toLowerCase(str.charAt(0)))
+ .append(str.substring(1))
+ .toString();
+ }
+
+ /**
+ * Swaps the case of a String changing upper and title case to + * lower case, and lower case to upper case.
+ * + *For a word based algorithm, see {@link WordUtils#swapCase(String)}.
+ * A null
input String returns null
.
+ * StringUtils.swapCase(null) = null + * StringUtils.swapCase("") = "" + * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone" + *+ * + *
NOTE: This method changed in Lang version 2.0. + * It no longer performs a word based algorithm. + * If you only use ASCII, you will notice no change. + * That functionality is available in WordUtils.
+ * + * @param str the String to swap case, may be null + * @return the changed String,null
if null String input
+ */
+ public static String swapCase(String str) {
+ int strLen;
+ if (str == null || (strLen = str.length()) == 0) {
+ return str;
+ }
+ StringBuffer buffer = new StringBuffer(strLen);
+
+ char ch = 0;
+ for (int i = 0; i < strLen; i++) {
+ ch = str.charAt(i);
+ if (Character.isUpperCase(ch)) {
+ ch = Character.toLowerCase(ch);
+ } else if (Character.isTitleCase(ch)) {
+ ch = Character.toLowerCase(ch);
+ } else if (Character.isLowerCase(ch)) {
+ ch = Character.toUpperCase(ch);
+ }
+ buffer.append(ch);
+ }
+ return buffer.toString();
+ }
+
+ /**
+ // Defaults
+ //-----------------------------------------------------------------------
+ /**
+ * Returns either the passed in String, or if the String is
+ * empty or null
, the value of defaultStr
.
+ * StringUtils.defaultIfEmpty(null, "NULL") = "NULL" + * StringUtils.defaultIfEmpty("", "NULL") = "NULL" + * StringUtils.defaultIfEmpty("bat", "NULL") = "bat" + *+ * + * @see StringUtils#defaultString(String, String) + * @param str the String to check, may be null + * @param defaultStr the default String to return + * if the input is empty ("") or
null
, may be null
+ * @return the passed in String, or the default
+ */
+ public static String defaultString(String str, String defaultStr) {
+ return StringUtils.isEmpty(str) ? defaultStr : str;
+ }
+
+ // Reversing
+ //-----------------------------------------------------------------------
+ /**
+ * Reverses a String as per {@link StringBuffer#reverse()}.
+ * + *A null
String returns null
.
+ * StringUtils.reverse(null) = null + * StringUtils.reverse("") = "" + * StringUtils.reverse("bat") = "tab" + *+ * + * @param str the String to reverse, may be null + * @return the reversed String,
null
if null String input
+ */
+ public static String reverse(String str) {
+ if (str == null) {
+ return null;
+ }
+ return new StringBuffer(str).reverse().toString();
+ }
+
+ // Abbreviating
+ //-----------------------------------------------------------------------
+ /**
+ * Abbreviates a String using ellipses. This will turn + * "Now is the time for all good men" into "Now is the time for..."
+ * + *Specifically: + *
str
is less than maxWidth
characters
+ * long, return it.(substring(str, 0, max-3) + "...")
.maxWidth
is less than 4
, throw an
+ * IllegalArgumentException
.maxWidth
.+ * StringUtils.abbreviate(null, *) = null + * StringUtils.abbreviate("", 4) = "" + * StringUtils.abbreviate("abcdefg", 6) = "abc..." + * StringUtils.abbreviate("abcdefg", 7) = "abcdefg" + * StringUtils.abbreviate("abcdefg", 8) = "abcdefg" + * StringUtils.abbreviate("abcdefg", 4) = "a..." + * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException + *+ * + * @param str the String to check, may be null + * @param maxWidth maximum length of result String, must be at least 4 + * @return abbreviated String,
null
if null String input
+ * @throws IllegalArgumentException if the width is too small
+ * @since 2.0
+ */
+ public static String abbreviate(String str, int maxWidth) {
+ return abbreviate(str, 0, maxWidth);
+ }
+
+ /**
+ * Abbreviates a String using ellipses. This will turn + * "Now is the time for all good men" into "...is the time for..."
+ * + *Works like abbreviate(String, int)
, but allows you to specify
+ * a "left edge" offset. Note that this left edge is not necessarily going to
+ * be the leftmost character in the result, or the first character following the
+ * ellipses, but it will appear somewhere in the result.
+ *
+ *
In no case will it return a String of length greater than
+ * maxWidth
.
+ * StringUtils.abbreviate(null, *, *) = null + * StringUtils.abbreviate("", 0, 4) = "" + * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..." + * StringUtils.abbreviate("abcdefghijklmno", 0, 10) = "abcdefg..." + * StringUtils.abbreviate("abcdefghijklmno", 1, 10) = "abcdefg..." + * StringUtils.abbreviate("abcdefghijklmno", 4, 10) = "abcdefg..." + * StringUtils.abbreviate("abcdefghijklmno", 5, 10) = "...fghi..." + * StringUtils.abbreviate("abcdefghijklmno", 6, 10) = "...ghij..." + * StringUtils.abbreviate("abcdefghijklmno", 8, 10) = "...ijklmno" + * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno" + * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno" + * StringUtils.abbreviate("abcdefghij", 0, 3) = IllegalArgumentException + * StringUtils.abbreviate("abcdefghij", 5, 6) = IllegalArgumentException + *+ * + * @param str the String to check, may be null + * @param offset left edge of source String + * @param maxWidth maximum length of result String, must be at least 4 + * @return abbreviated String,
null
if null String input
+ * @throws IllegalArgumentException if the width is too small
+ * @since 2.0
+ */
+ public static String abbreviate(String str, int offset, int maxWidth) {
+ if (str == null) {
+ return null;
+ }
+ if (maxWidth < 4) {
+ throw new IllegalArgumentException("Minimum abbreviation width is 4");
+ }
+ if (str.length() <= maxWidth) {
+ return str;
+ }
+ if (offset > str.length()) {
+ offset = str.length();
+ }
+ if ((str.length() - offset) < (maxWidth - 3)) {
+ offset = str.length() - (maxWidth - 3);
+ }
+ if (offset <= 4) {
+ return str.substring(0, maxWidth - 3) + "...";
+ }
+ if (maxWidth < 7) {
+ throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
+ }
+ if ((offset + (maxWidth - 3)) < str.length()) {
+ return "..." + abbreviate(str.substring(offset), maxWidth - 3);
+ }
+ return "..." + str.substring(str.length() - (maxWidth - 3));
+ }
+
+ /**
+
+
+ /**
+ /**
+
+ // ToString
+ //-----------------------------------------------------------------------
+ /**
+ * Gets the toString
of an Object
returning
+ * an empty string ("") if null
input.
+ * ObjectUtils.toString(null) = "" + * ObjectUtils.toString("") = "" + * ObjectUtils.toString("bat") = "bat" + * ObjectUtils.toString(Boolean.TRUE) = "true" + *+ * + * @see StringUtils#defaultString(String) + * @see String#valueOf(Object) + * @param obj the Object to
toString
, may be null
+ * @return the passed in Object's toString, or nullStr if null
input
+ * @since 2.0
+ */
+ public static String toString(Object obj) {
+ return obj == null ? "" : obj.toString();
+ }
+}
diff --git a/src/test/java/org/jboss/seam/render/test/BundledHelpersTest.java b/src/test/java/org/jboss/seam/render/test/BundledHelpersTest.java
new file mode 100644
index 0000000..1454d3b
--- /dev/null
+++ b/src/test/java/org/jboss/seam/render/test/BundledHelpersTest.java
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.render.test;
+
+import org.jboss.seam.render.template.compiler.CustomTemplateCompiler;
+import org.junit.Test;
+import org.mvel2.templates.CompiledTemplate;
+import org.mvel2.templates.TemplateRuntime;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+
+/**
+ * @author Pete Royle
+ */
+public class BundledHelpersTest {
+
+ @Test
+ public void testStringUtils() throws Exception {
+ testBundledHelper("TheInpu...", "@{render.abbreviate('TheInputString', 10)}");
+ testBundledHelper("...putSt...", "@{render.abbreviate('TheInputString', 5, 11)}");
+ testBundledHelper("TheInputString", "@{render.capitalize('theInputString')}");
+ testBundledHelper(" TheInputString ", "@{render.center('TheInputString', 20)}");
+ testBundledHelper("TheInputString", "@{render.defaultString('TheInputString', 'BlahBlah')}");
+ testBundledHelper("BlahBlah", "@{render.defaultString('', 'BlahBlah')}");
+ testBundledHelper("BlahBlah", "@{render.defaultString(null, 'BlahBlah')}");
+ testBundledHelper("The Input String", "@{render.join(new String[]{'The', 'Input', 'String'}, ' ')}");
+ testBundledHelper(" TheInputString", "@{render.leftPad('TheInputString', 20)}");
+ testBundledHelper("XXXXXXTheInputString", "@{render.leftPad('TheInputString', 20, 'X')}");
+ testBundledHelper("theinputstring", "@{render.lowerCase('TheInputString')}");
+ testBundledHelper("TheOutputString", "@{render.replace('TheInputString', 'In', 'Out')}");
+ testBundledHelper("TheInputString ", "@{render.rightPad('TheInputString', 20)}");
+ testBundledHelper("TheInputStringXXXXXX", "@{render.rightPad('TheInputString', 20, 'X')}");
+ testBundledHelper(new String[]{"The", "Input", "String"}, "@{render.split('The Input String')}");
+ testBundledHelper(new String[]{"TheI", "putStri", "g"}, "@{render.split('TheInputString', 'n')}");
+ testBundledHelper("tHEiNPUTsTRING", "@{render.swapCase('TheInputString')}");
+ testBundledHelper("TheInputString", "@{render.trim(' TheInputString ')}");
+ testBundledHelper("theInputString", "@{render.uncapitalize('TheInputString')}");
+ testBundledHelper("THEINPUTSTRING", "@{render.upperCase('TheInputString')}");
+ }
+
+ private void testBundledHelper(Object expectedResult, String mvelExpression) throws SecurityException, NoSuchMethodException {
+ CompiledTemplate template = CustomTemplateCompiler.compileTemplate(mvelExpression);
+ Object result = TemplateRuntime.execute(template);
+ if (result instanceof Object[]) {
+ assertArrayEquals((Object[]) expectedResult, (Object[]) result);
+ } else {
+ assertEquals(expectedResult, result);
+ }
+ }
+
+}