/*
* Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The
* University of Hong Kong (HKU). All Rights Reserved.
*
* This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1]
*
* [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/
package hk.hku.cecid.piazza.commons.util;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A StringUtilities is a convenient class for handling some common text
* processing.
*
* @author Hugo Y. K. Lam
*
*/
public final class StringUtilities {
private static final String DEFAULT_VALUE_SEPARTOR = ":";
public final static String LINE_SEPARATOR = System.getProperty("line.separator", "\n");
/**
* Creates new StringUtilities
*/
private StringUtilities() {
}
/**
* Tokenizes a given string according to the specified delimiters. The
* characters in the delim argument are the delimiters for separating
* tokens. Delimiter characters themselves will not be treated as tokens.
*
* @param str a string to be parsed.
* @param delim the delimiters.
* @return the tokens in a string array.
*/
public static String[] tokenize(String str, String delim) {
return ArrayUtilities.toArray(str, delim);
}
/**
* Tokenizes a given string according to a fixed length. If the last token's
* length is less than the fixed length specified, it will be ignored.
*
* @param str a string to be parsed.
* @param fixedLength the fixed length.
* @return the tokens in a string array.
*/
public static String[] tokenize(String str, int fixedLength) {
ArrayList tokens = new ArrayList();
if (str != null && fixedLength > 0) {
for (int i = 0; i < str.length(); i += fixedLength) {
int next = i + fixedLength;
if (next > str.length()) {
break;
}
tokens.add(str.substring(i, next));
}
}
return (String[]) tokens.toArray(new String[]{});
}
/**
* Concatenates a string array (string tokens) into a string with the
* specified delimiter string.
*
* @param tokens a string array to be concatenated.
* @param delim the delimiter.
* @return the concatenated string.
*/
public static String concat(String[] tokens, String delim) {
return concat(tokens, "", "", delim);
}
/**
* Concatenates a string array (string tokens) into a string with the
* specified delimiter string, token's prefix, and token's suffix.
*
* @param tokens a string array to be concatenated.
* @param tokenPrefix the token's prefix to be concatenated.
* @param tokenSuffix the token's suffix to be concatenated.
* @param delim the delimiter.
* @return the concatenated string.
*/
public static String concat(String[] tokens, String tokenPrefix,
String tokenSuffix, String delim) {
String s = "";
if (tokens != null) {
if (tokenPrefix == null) {
tokenPrefix = "";
}
if (tokenSuffix == null) {
tokenSuffix = "";
}
if (delim == null) {
delim = "";
}
for (int i = 0; i < tokens.length; i++) {
s += tokenPrefix + tokens[i] + tokenSuffix;
if (i + 1 < tokens.length) {
s += delim;
}
}
}
return s;
}
/**
* Checks if a given string array contains the specified search string.
*
* @param tokens a string array to be searched.
* @param target the target search string.
* @return true if the given string array contains the specified search
* string, false otherwise.
*/
public static boolean contains(String[] tokens, String target) {
if (tokens != null) {
for (int i = 0; i < tokens.length; i++) {
if (tokens[i] == null) {
if (target == null) {
return true;
}
}
else {
if (tokens[i].equals(target)) {
return true;
}
}
}
}
return false;
}
/**
* Repeats a given string in the specified number of times, then
* concatenates and returns it.
*
* @param s a string to be repeated and concatenated.
* @param occurs the number of times of the given string to be repeated.
* @return the concatenated string.
*/
public static String repeat(String s, int occurs) {
String result = "";
if (s != null && occurs > 0) {
for (int i = 0; i < occurs; i++) {
result += s;
}
}
return result;
}
/**
* Checks if a given string contains only digits.
*
* @param s a string to be checked.
* @return true if the given string contains only digits, false otherwise.
*/
public static boolean isAllDigit(String s) {
if (s == null || s.equals("")) {
return false;
}
else {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (!Character.isDigit(c)) {
return false;
}
}
return true;
}
}
/**
* Adds leading zeros to the given string to the specified length. Nothing
* will be done if the length of the given string is equal to or greater
* than the specified length.
*
* @param s the source string.
* @param len the length of the target string.
* @return the string after adding leading zeros.
*/
public static String addLeadingZero(String s, int len) {
return addLeadingCharacter(s, '0', len);
}
/**
* Adds leading spaces to the given string to the specified length. Nothing
* will be done if the length of the given string is equal to or greater
* than the specified length.
*
* @param s the source string.
* @param len the length of the target string.
* @return the string after adding leading spaces.
*/
public static String addLeadingSpace(String s, int len) {
return addLeadingCharacter(s, ' ', len);
}
/**
* Adds specified leading characters to the specified length. Nothing will
* be done if the length of the given string is equal to or greater than the
* specified length.
*
* @param s the source string.
* @param c the leading character(s) to be added.
* @param len the length of the target string.
* @return the string after adding the specified leading character(s).
*/
public static String addLeadingCharacter(String s, char c, int len) {
while (s != null && s.length() < len) {
s = c + s;
}
return s;
}
/**
* Removes leading zeros from the given string, if any.
*
* @param s the source string.
* @return the string after removing leading zeros.
*/
public static String removeLeadingZero(String s) {
return removeLeadingCharacter(s, '0');
}
/**
* Removes leading spaces from the given string, if any.
*
* @param s the source string.
* @return the string after removing leading spaces.
*/
public static String removeLeadingSpace(String s) {
return removeLeadingCharacter(s, ' ');
}
/**
* Removes specified leading characters from the given string, if any.
*
* @param s the source string.
* @param c the leading character(s) to be removed.
* @return the string after removing the specified leading character(s).
*/
public static String removeLeadingCharacter(String s, char c) {
while (s != null && s.length() > 0 && s.charAt(0) == c) {
s = s.substring(1, s.length());
}
return s;
}
/**
* Appends zeros to the given string to the specified length. Nothing will
* be done if the length of the given string is equal to or greater than the
* specified length.
*
* @param s the source string.
* @param len the length of the target string.
* @return the string after appending zeros.
*/
public static String appendZero(String s, int len) {
return appendCharacter(s, '0', len);
}
/**
* Appends spaces to the given string to the specified length. Nothing will
* be done if the length of the given string is equal to or greater than the
* specified length.
*
* @param s the source string.
* @param len the length of the target string.
* @return @return the string after appending spaces.
*/
public static String appendSpace(String s, int len) {
return appendCharacter(s, ' ', len);
}
/**
* Appends specified characters to the given string to the specified length.
* Nothing will be done if the length of the given string is equal to or
* greater than the specified length.
*
* @param s the source string.
* @param c the character(s) to be appended.
* @param len the length of the target string.
* @return @return the string after appending the specified character(s).
*/
public static String appendCharacter(String s, char c, int len) {
while (s != null && s.length() < len) {
s += c;
}
return s;
}
/**
* Checks if a given string is null or empty after trimmed.
*
* @param s the string to be checked.
* @return true if the given string is null or empty after trimmed, false
* otherwise.
*/
public static boolean isEmptyString(String s) {
return (s == null || (s.trim()).equals(""));
}
/**
* Returns a string representation of the given throwable object, empty string if it
* is null. The resulted string contains a cause trace of the given throwable object.
*
* @param e the throwable object for getting its string representation.
* @return a string represenation of the given Object.
*/
public static String toString(Throwable e) {
if (e == null) {
return "";
}
else {
String s = getExceptionString(e);
Throwable cause = e.getCause();
while (cause != null) {
s += StringUtilities.LINE_SEPARATOR + "\tby "
+ getExceptionString(cause);
cause = cause.getCause();
}
return s;
}
}
/**
* Gets the exception description.
*
* @param e the exception.
* @return the exception description.
*/
private static String getExceptionString(Throwable e) {
if (e == null) {
return "";
}
else {
String s = e.getClass().getName();
String m = e.getMessage();
if (m != null) {
s += ": " + m;
}
return s;
}
}
/**
* Returns a string representation of the given object, empty string if it
* is null.
*
* @param obj the object for getting its string representation.
* @return a string represenation of the given Object.
*/
public static String toString(Object obj) {
if (obj == null) {
return "";
}
else {
return obj.toString();
}
}
/**
* Returns a string representation of the given Date object of the form:
* d MMM yyyy hh:mm:ss GMT
*
* @param d the date.
* @return the GMT string representation of the given date.
*/
public static String toGMTString(Date d) {
SimpleDateFormat formatter = new SimpleDateFormat("d MMM yyyy HH:mm:ss z", Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
return formatter.format(d);
}
/**
* Converts the given string into an array of characters.
*
* @param s the string to be converted.
* @return an array of characters representing the given string or
* an empty array if the given string is null or empty.
*/
public static char[] toCharArray(String s) {
return s==null? new char[]{}:s.toCharArray();
}
/**
* Trims a given string. An empty string will be returned if the given
* string is null.
*
* @param s the string to be trimmed.
* @return the trimmed string.
*/
public static String trim(String s) {
if (s == null) {
return "";
}
else {
return s.trim();
}
}
/**
* Trims the given string. If the given string starts with the specified
* prefix and ends with the specified suffix, both the prefix and the suffix
* will be trimmed out.
*
* @param s the string to be trimmed.
* @param prefix the prefix.
* @param suffix the suffix.
* @return the trimmed string.
*/
public static String trim(String s, String prefix, String suffix) {
if (isWrappedWith(s, prefix, suffix)) {
return s.substring(getLength(prefix), s.length()-getLength(suffix));
}
else {
return s;
}
}
/**
* Trims a given string and then verifies its size against the specified
* size. If the sizes do not match, null will be returned.
*
* @param s the string to be trimmed and verified.
* @param size the size for the verification.
* @return the trimmed string or null if the size verification failed.
*/
public static String trimAndVerifySize(String s, int size) {
s = trim(s);
if (s.length() != size) {
return null;
}
else {
return s;
}
}
/**
* Wraps a given string with the specified prefix and suffix, if it is not
* alreay wrapped.
*
* @param s the string to be wrapped.
* @param prefix the prefix.
* @param suffix the suffix.
* @return the wrapped string.
*/
public static String wraps(String s , String prefix, String suffix) {
if (isWrappedWith(s, prefix, suffix)) {
return s;
}
else {
return prefix + s + suffix;
}
}
/**
* Adds a prefix to a given string if it does not start with.
*
* @param s the string to be added.
* @param prefix the prefix.
* @return the string with the specified prefix.
*/
public static String addPrefix(String s, String prefix) {
if (s == null) {
return prefix;
}
else {
if (s.startsWith(prefix)) {
return s;
}
else {
return prefix + s;
}
}
}
/**
* Adds a suffix to a given string if it does not end with.
*
* @param s the string to be added.
* @param suffix the suffix.
* @return the string with the specified suffix.
*/
public static String addSuffix(String s, String suffix) {
if (s == null) {
return suffix;
}
else {
if (s.endsWith(suffix)) {
return s;
}
else {
return s + suffix;
}
}
}
/**
* Checks if the given string is wrapped with the specified prefix and
* suffix.
*
* @param s the string to be checked.
* @param prefix the prefix.
* @param suffix the suffix.
* @return true if the given string is wrapped with the prefix and suffix.
*/
public static boolean isWrappedWith(String s, String prefix, String suffix) {
if (s == null) {
return false;
}
else {
return s.startsWith(prefix==null? "":prefix) &&
s.endsWith(suffix==null? "":suffix);
}
}
/**
* Gets the length of the given string.
*
* @param s the string.
* @return the length of the given string or 0 if it is null.
*/
public static int getLength(String s) {
if (s == null) {
return 0;
}
else {
return s.length();
}
}
/**
* Converts the tokenized string into a string array.
*
* @param s the string to be tokenized.
* @param delim the delimiters.
* @param size the size of the converted array.
* @return the string array.
*/
public static String[] toArray(String s, String delim, int size) {
if (size < 0) {
size = 0;
}
String[] array = new String[size];
String[] tokens = tokenize(s, delim);
for (int i=0; i<array.length && i<tokens.length; i++) {
array[i] = tokens[i];
}
return array;
}
/**
* Converts a given string into a string array.
*
* @param s the string to be converted.
* @param occurs the number of occurrences.
* @return the string array.
*/
public static String[] toArray(String s, int occurs) {
if (occurs < 0) {
occurs = 0;
}
String[] array = new String[occurs];
for (int i=0; i<array.length; i++) {
array[i] = s;
}
return array;
}
/**
* Converts a given string into a string array.
* The resulted array will contain only one element, which is the specified
* string parameter.
*
* @param s the string to be converted.
* @return the string array.
*/
public static String[] toArray(String s) {
return toArray(s, 1);
}
/**
* Parses the given string and returns the integer value it represents.
*
* @param s the string to be parsed.
* @return the integer value the string represents or Integer.MIN_VALUE if
* unable to parse the string.
*/
public static int parseInt(String s) {
try {
return Integer.parseInt(s);
}
catch (Exception e) {
return Integer.MIN_VALUE;
}
}
/**
* Parses the given string and returns the integer value it represents.
*
* @param s the string to be parsed.
* @return the integer value the string represents or the default value if
* unable to parse the string.
*/
public static int parseInt(String s, int def) {
try {
return Integer.parseInt(s);
}
catch (Exception e) {
return def;
}
}
/**
* Parses the given string and returns the long value it represents.
*
* @param s the string to be parsed.
* @return the long value the string represents or Long.MIN_VALUE if
* unable to parse the string.
*/
public static long parseLong(String s) {
return parseLong(s, Long.MIN_VALUE);
}
/**
* Parses the given string and returns the long value it represents.
*
* @param s the string to be parsed.
* @return the long value the string represents or the default value if
* unable to parse the string.
*/
public static long parseLong(String s, long def) {
try {
return Long.parseLong(s);
}
catch (Exception e) {
return def;
}
}
/**
* Parses the given string and returns the double value it represents.
*
* @param s the string to be parsed.
* @return the double value the string represents or Double.NaN if
* unable to parse the string.
*/
public static double parseDouble(String s) {
try {
return Double.parseDouble(s);
}
catch (Exception e) {
return Double.NaN;
}
}
/**
* Parses the given string and returns the double value it represents.
*
* @param s the string to be parsed.
* @return the double value the string represents or the default value if
* unable to parse the string.
*/
public static double parseDouble(String s, double def) {
try {
return Double.parseDouble(s);
}
catch (Exception e) {
return def;
}
}
/**
* Parses the given string and returns the boolean value it represents.
*
* @param s the string to be parsed.
* @return true if and only if the given string equals, ignoring case, "true".
*/
public static boolean parseBoolean(String s) {
if (s == null) {
return false;
}
else {
return new Boolean(s).booleanValue();
}
}
/**
* Parses the given string and returns the boolean value it represents.
*
* @param s the string to be parsed.
* @param def the default boolean value when <code>s</code> is null.
* @return true if and only if the given string equals, ignoring case, "true".
*/
public static boolean parseBoolean(String s, boolean def)
{
if (s == null)
{
return def;
}
else
{
return new Boolean(s).booleanValue();
}
}
/**
* To Convert the byte array to the String in Hexdecimal format
* @param b byte array to convert
* @return String in hexdecimal representation
* @throws Exception
*/
public static String toHexString(byte[] b) throws Exception {
String result = "";
for (int i=0; i < b.length; i++) {
result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
}
return result;
}
/**
* @param string
* @param regex
* @param group the <b>one-based</b> index of the target group.
* The default group is the zeroth group, which is the whole expression
* @return each match of the specified group
*/
public static List<String> extractRegexMulti(String string, String regex, int group) {
List<String> result = new ArrayList<String>();
if (string == null) {
return result;
}
Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
if (group > matcher.groupCount()) {
} else {
result.add(matcher.group(group));
}
}
return result;
}
public static String propertyValue(String value) {
return propertyValue(value,System.getProperties());
}
public static String propertyValue(String value, Properties props) {
if(value == null) {
return null;
}
boolean hadDefault = false;
String result = value;
if(result.contains("${")) {
List<String> defaultVars = StringUtilities.extractRegexMulti(result,"\\$\\{([^{}]+)\\}",1);
for(String defaultVar : defaultVars) {
result = result.replace("${" + defaultVar + "}", propertyGet(defaultVar,props));
}
if(result != null && result.isEmpty()) {
return null;
}
List<String> variables = StringUtilities.extractRegexMulti(result,"\\$\\{([^}]+)\\}",1);
for(String var: variables) {
//split the varible into the key and default value (if present)
//in the form ${property:defaultValue}
String [] variable = splitFirst(var,DEFAULT_VALUE_SEPARTOR);
//Is the variable in the System Properties
//If so replace the variable with it
if(props.containsKey(variable[0])) {
result = result.replace("${"+ var + "}", props.getProperty(variable[0]));
}
else if(variable[1] != null) {
//Otherwise use the default value
hadDefault = true;
result = result.replace("${"+ var + "}", variable[1]);
}
}
}
if(hadDefault && "".equals(result)) {
return null;
}
return result;
}
public static String propertyGet(String property, Properties props) {
return propertyGet(new RealEnvironment(), property, props);
}
public static String propertyGet(EnvironmentHandler environmentHandler, String property, Properties props) {
//split the varible into the key and default value (if present)
//in the form ${property:defaultValue}
String result = property;
String [] variable = splitFirst(property,DEFAULT_VALUE_SEPARTOR);
String envValue = javaParamToEnvironmentParam(environmentHandler, variable[0]);
//Is the variable in the System Properties
//If so replace the variable with it
if(!StringUtilities.isEmptyString(envValue)) {
result = envValue;
}
else if(props.containsKey(variable[0])) {
result = props.getProperty(variable[0]);
}
else if(variable[1] != null) {
//Otherwise use the default value
result =variable[1];
}
return result;
}
public static String javaParamToEnvironmentParam(EnvironmentHandler environmentHandler, String s) {
if (isEmptyString(s))
return s;
String envVar = s.toUpperCase().replaceAll("[.]", "_");
return environmentHandler.getenv(envVar);
}
public static String[] splitFirst(String value, String separator)
{
if(value == null) {
return null;
}
String [] result = new String[2];
int pos = value.indexOf(separator);
//separator can't be the first element
if(pos > 0) {
result[0] = value.substring(0,pos);
result[1] = value.substring(pos+1, value.length());
} else {
result[0] = value;
result[1] = null;
}
return result;
}
public abstract static class EnvironmentHandler {
public abstract String getenv(String envVar);
}
public static class RealEnvironment extends EnvironmentHandler {
public String getenv(String envVar) {
return System.getenv(envVar);
}
}
}