org.devefx.validator.util.StringUtils Maven / Gradle / Ivy
Show all versions of validator-web Show documentation
/*
* Copyright 2016-2017, Youqian Yue ([email protected]).
*
* 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.devefx.validator.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
public class StringUtils {
/**
* Constant representing the empty string, equal to ""
*/
public static final String EMPTY_STRING = "";
/**
* Constant representing the default delimiter character (comma), equal to ','
*/
public static final char DEFAULT_DELIMITER_CHAR = ',';
/**
* Constant representing the default quote character (double quote), equal to '"'
*/
public static final char DEFAULT_QUOTE_CHAR = '"';
/**
* Check that the given CharSequence is neither {@code null} nor of length 0.
* Note: Will return {@code true} for a CharSequence that purely consists of whitespace.
*
* StringUtils.hasLength(null) = false
* StringUtils.hasLength("") = false
* StringUtils.hasLength(" ") = true
* StringUtils.hasLength("Hello") = true
*
* @param str the CharSequence to check (may be {@code null})
* @return {@code true} if the CharSequence is not null and has length
* @see #hasText(String)
*/
public static boolean hasLength(CharSequence str) {
return (str != null && str.length() > 0);
}
/**
* Check that the given {@code String} is neither {@code null} nor of length 0.
* Note: this method returns {@code true} for a {@code String} that
* purely consists of whitespace.
* @param str the {@code String} to check (may be {@code null})
* @return {@code true} if the {@code String} is not {@code null} and has length
* @see #hasLength(CharSequence)
* @see #hasText(String)
*/
public static boolean hasLength(String str) {
return hasLength((CharSequence) str);
}
/**
* Check whether the given CharSequence has actual text.
* More specifically, returns {@code true} if the string not {@code null},
* its length is greater than 0, and it contains at least one non-whitespace character.
*
* StringUtils.hasText(null) = false
* StringUtils.hasText("") = false
* StringUtils.hasText(" ") = false
* StringUtils.hasText("12345") = true
* StringUtils.hasText(" 12345 ") = true
*
* @param str the CharSequence to check (may be {@code null})
* @return {@code true} if the CharSequence is not {@code null},
* its length is greater than 0, and it does not contain whitespace only
* @see Character#isWhitespace
*/
public static boolean hasText(CharSequence str) {
if (!hasLength(str)) {
return false;
}
int strLen = str.length();
for (int i = 0; i < strLen; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return true;
}
}
return false;
}
/**
* Check whether the given String has actual text.
* More specifically, returns {@code true} if the string not {@code null},
* its length is greater than 0, and it contains at least one non-whitespace character.
* @param str the String to check (may be {@code null})
* @return {@code true} if the String is not {@code null}, its length is
* greater than 0, and it does not contain whitespace only
* @see #hasText(CharSequence)
*/
public static boolean hasText(String str) {
return hasText((CharSequence) str);
}
/**
* Tokenize the given String into a String array via a StringTokenizer.
* Trims tokens and omits empty tokens.
* The given delimiters string is supposed to consist of any number of
* delimiter characters. Each of those characters can be used to separate
* tokens. A delimiter is always a single character; for multi-character
* delimiters
* @param str the String to tokenize
* @param delimiters the delimiter characters, assembled as String
* (each of those characters is individually considered as delimiter).
* @return an array of the tokens
* @see java.util.StringTokenizer
* @see String#trim()
*/
public static String[] tokenizeToStringArray(String str, String delimiters) {
return tokenizeToStringArray(str, delimiters, true, true);
}
/**
* Tokenize the given String into a String array via a StringTokenizer.
*
The given delimiters string is supposed to consist of any number of
* delimiter characters. Each of those characters can be used to separate
* tokens. A delimiter is always a single character; for multi-character
* delimiters, consider using {@code delimitedListToStringArray}
* @param str the String to tokenize
* @param delimiters the delimiter characters, assembled as String
* (each of those characters is individually considered as delimiter)
* @param trimTokens trim the tokens via String's {@code trim}
* @param ignoreEmptyTokens omit empty tokens from the result array
* (only applies to tokens that are empty after trimming; StringTokenizer
* will not consider subsequent delimiters as token in the first place).
* @return an array of the tokens ({@code null} if the input String
* was {@code null})
* @see java.util.StringTokenizer
* @see String#trim()
*/
public static String[] tokenizeToStringArray(
String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {
if (str == null) {
return null;
}
StringTokenizer st = new StringTokenizer(str, delimiters);
List tokens = new ArrayList();
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (trimTokens) {
token = token.trim();
}
if (!ignoreEmptyTokens || token.length() > 0) {
tokens.add(token);
}
}
return toStringArray(tokens);
}
/**
* Copy the given Collection into a String array.
* The Collection must contain String elements only.
* @param collection the Collection to copy
* @return the String array ({@code null} if the passed-in
* Collection was {@code null})
*/
public static String[] toStringArray(Collection collection) {
if (collection == null) {
return null;
}
return collection.toArray(new String[collection.size()]);
}
/**
* Returns a 'cleaned' representation of the specified argument. 'Cleaned' is defined as the following:
*
*
* - If the specified
String
is null
, return null
* - If not
null
, {@link String#trim() trim()} it.
* - If the trimmed string is equal to the empty String (i.e. ""), return
null
* - If the trimmed string is not the empty string, return the trimmed version
.
*
*
* Therefore this method always ensures that any given string has trimmed text, and if it doesn't, null
* is returned.
*
* @param in the input String to clean.
* @return a populated-but-trimmed String or null
otherwise
*/
public static String clean(String in) {
String out = in;
if (in != null) {
out = in.trim();
if (out.equals(EMPTY_STRING)) {
out = null;
}
}
return out;
}
public static String[] split(String line) {
return split(line, DEFAULT_DELIMITER_CHAR);
}
public static String[] split(String line, char delimiter) {
return split(line, delimiter, DEFAULT_QUOTE_CHAR);
}
public static String[] split(String line, char delimiter, char quoteChar) {
return split(line, delimiter, quoteChar, quoteChar);
}
public static String[] split(String line, char delimiter, char beginQuoteChar, char endQuoteChar) {
return split(line, delimiter, beginQuoteChar, endQuoteChar, false, true);
}
/**
* Splits the specified delimited String into tokens, supporting quoted tokens so that quoted strings themselves
* won't be tokenized.
*
* This method's implementation is very loosely based (with significant modifications) on
* Glen Smith's open-source
* CSVReader.java
* file.
*
* That file is Apache 2.0 licensed as well, making Glen's code a great starting point for us to modify to
* our needs.
*
* @param aLine the String to parse
* @param delimiter the delimiter by which the line argument is to be split
* @param beginQuoteChar the character signifying the start of quoted text (so the quoted text will not be split)
* @param endQuoteChar the character signifying the end of quoted text
* @param retainQuotes if the quotes themselves should be retained when constructing the corresponding token
* @param trimTokens if leading and trailing whitespace should be trimmed from discovered tokens.
* @return the tokens discovered from parsing the given delimited line.
*/
public static String[] split(String aLine, char delimiter, char beginQuoteChar, char endQuoteChar,
boolean retainQuotes, boolean trimTokens) {
String line = clean(aLine);
if (line == null) {
return null;
}
List tokens = new ArrayList();
StringBuilder sb = new StringBuilder();
boolean inQuotes = false;
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
if (c == beginQuoteChar) {
// this gets complex... the quote may end a quoted block, or escape another quote.
// do a 1-char lookahead:
if (inQuotes // we are in quotes, therefore there can be escaped quotes in here.
&& line.length() > (i + 1) // there is indeed another character to check.
&& line.charAt(i + 1) == beginQuoteChar) { // ..and that char. is a quote also.
// we have two quote chars in a row == one quote char, so consume them both and
// put one on the token. we do *not* exit the quoted text.
sb.append(line.charAt(i + 1));
i++;
} else {
inQuotes = !inQuotes;
if (retainQuotes) {
sb.append(c);
}
}
} else if (c == endQuoteChar) {
inQuotes = !inQuotes;
if (retainQuotes) {
sb.append(c);
}
} else if (c == delimiter && !inQuotes) {
String s = sb.toString();
if (trimTokens) {
s = s.trim();
}
tokens.add(s);
sb = new StringBuilder(); // start work on next token
} else {
sb.append(c);
}
}
String s = sb.toString();
if (trimTokens) {
s = s.trim();
}
tokens.add(s);
return tokens.toArray(new String[tokens.size()]);
}
/**
* Convenience method to return a Collection as a delimited (e.g. CSV)
* String. E.g. useful for {@code toString()} implementations.
* @param coll the Collection to display
* @param delim the delimiter to use (probably a ",")
* @param prefix the String to start each element with
* @param suffix the String to end each element with
* @return the delimited String
*/
public static String collectionToDelimitedString(Collection> coll, String delim, String prefix, String suffix) {
if (coll == null || coll.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
Iterator> it = coll.iterator();
while (it.hasNext()) {
sb.append(prefix).append(it.next()).append(suffix);
if (it.hasNext()) {
sb.append(delim);
}
}
return sb.toString();
}
/**
* Convenience method to return a Collection as a delimited (e.g. CSV)
* String. E.g. useful for {@code toString()} implementations.
* @param coll the Collection to display
* @param delim the delimiter to use (probably a ",")
* @return the delimited String
*/
public static String collectionToDelimitedString(Collection> coll, String delim) {
return collectionToDelimitedString(coll, delim, "", "");
}
/**
* Convenience method to return a Collection as a CSV String.
* E.g. useful for {@code toString()} implementations.
* @param coll the Collection to display
* @return the delimited String
*/
public static String collectionToCommaDelimitedString(Collection> coll) {
return collectionToDelimitedString(coll, ",");
}
}