/**
* Licensed to JumpMind Inc under one or more contributor
* license agreements. See the NOTICE file distributed
* with this work for additional information regarding
* copyright ownership. JumpMind Inc licenses this file
* to you under the GNU General Public License, version 3.0 (GPLv3)
* (the "License"); you may not use this file except in compliance
* with the License.
*
* You should have received a copy of the GNU General Public License,
* version 3.0 (GPLv3) along with this library; if not, see
* <http://www.gnu.org/licenses/>.
*
* 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.jumpmind.util;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.FastDateFormat;
import org.jumpmind.exception.ParseException;
public final class FormatUtils {
public static final String[] TIMESTAMP_PATTERNS = { "yyyy-MM-dd HH:mm:ss.S",
"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd HH:mm", "yyyy-MM-dd",
"HH:mm:ss.S", "HH:mm:ss" };
public static final String[] TIME_PATTERNS = { "HH:mm:ss.S", "HH:mm:ss",
"yyyy-MM-dd HH:mm:ss.S", "yyyy-MM-dd HH:mm:ss" };
public static final FastDateFormat TIMESTAMP_FORMATTER = FastDateFormat
.getInstance("yyyy-MM-dd HH:mm:ss.SSS");
public static final FastDateFormat TIME_FORMATTER = FastDateFormat.getInstance("HH:mm:ss.SSS");
public final static String WILDCARD = "*";
public final static String NEGATE_TOKEN = "!";
public final static int MAX_CHARS_TO_LOG = 1000;
private static Pattern pattern = Pattern.compile("\\$\\((.+?)\\)");
private FormatUtils() {
}
public static String replace(String prop, String replaceWith, String sourceString) {
return StringUtils.replace(sourceString, "$(" + prop + ")", replaceWith);
}
public static String replaceToken(String text, String tokenToReplace, String replaceWithText,
boolean matchUsingPrefixSuffix) {
Map<String, String> replacements = new HashMap<String, String>(1);
replacements.put(tokenToReplace, replaceWithText);
return replaceTokens(text, replacements, matchUsingPrefixSuffix);
}
/**
* Replace the keys found in the target text with the values found in the
* replacements map.
*
* @param text
* The text to replace
* @param replacements
* The map that contains the replacement values
* @param matchUsingPrefixSuffix
* If true, look for the $(key) pattern to replace. If false,
* just replace the key outright.
* @return The text with the token keys replaced
*/
public static String replaceTokens(String text, Map<?, ?> replacements,
boolean matchUsingPrefixSuffix) {
if (text != null && replacements != null && replacements.size() > 0) {
if (matchUsingPrefixSuffix) {
Matcher matcher = pattern.matcher(text);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
String[] match = matcher.group(1).split("\\|");
String replacement = (String)replacements.get(match[0]);
if (replacement != null) {
matcher.appendReplacement(buffer, "");
if (match.length == 2) {
replacement = formatString(match[1], replacement);
}
buffer.append(replacement);
}
}
matcher.appendTail(buffer);
text = buffer.toString();
} else {
for (Object key : replacements.keySet()) {
text = text.replaceAll(key.toString(), (String)replacements.get(key));
}
}
}
return text;
}
public static String formatString(String format, String arg) {
if (format.indexOf("d") >= 0 || format.indexOf("u") >= 0 || format.indexOf("i") >= 0) {
return String.format(format, Long.parseLong(arg));
} else if (format.indexOf("e") >= 0 || format.indexOf("f") >= 0) {
return String.format(format, Double.valueOf(arg));
} else {
return String.format(format, arg);
}
}
public static boolean toBoolean(String value) {
if (StringUtils.isNotBlank(value)) {
if (value.equals("1")) {
return true;
} else if (value.equals("0")) {
return false;
} else {
return Boolean.parseBoolean(value);
}
} else {
return false;
}
}
public static boolean isMixedCase(String text) {
char[] chars = text.toCharArray();
boolean upper = false;
boolean lower = false;
for (char ch : chars) {
upper |= Character.isUpperCase(ch);
lower |= Character.isLowerCase(ch);
}
return upper && lower;
}
public static boolean isWildCardMatch(String text, String pattern, boolean ignoreCase) {
boolean match = isWildCardMatch(text, pattern);
if (ignoreCase && !match) {
match = isWildCardMatch(text.toLowerCase(), pattern);
if (!match) {
match = isWildCardMatch(text.toUpperCase(), pattern);
}
}
return match;
}
public static boolean isWildCardMatch(String text, String pattern) {
boolean match = true;
if (pattern.startsWith(NEGATE_TOKEN)) {
pattern = pattern.substring(1);
}
// Create the cards by splitting using a RegEx. If more speed
// is desired, a simpler character based splitting can be done.
String[] cards = pattern.split("\\" + WILDCARD);
for(int i = 0; i < cards.length; i++) {
String card = cards[i];
boolean foundToken = false;
if (i == 0 && !pattern.startsWith("*")) {
foundToken = text.startsWith(card);
} else {
foundToken = text.indexOf(card) != -1;
}
// Card not detected in the text.
if (!foundToken) {
return !match;
}
// Move ahead, towards the right of the text.
text = text.substring(text.indexOf(card) + card.length());
}
return match;
}
/**
* Word wrap a string where the line size for the first line is different
* than the lines sizes for the other lines.
*
* @param str
* @param firstLineSize
* @param nonFirstLineSize
* @return
*/
public static String[] wordWrap(String str, int firstLineSize, int nonFirstLineSize) {
String[] lines = wordWrap(str, firstLineSize);
if (lines.length > 1 && firstLineSize != nonFirstLineSize) {
// More than one line. Re-wrap the non-first lines with the non
// first line size
String notFirstLinesString = StringUtils.join(lines, " ", 1, lines.length);
String[] nonFirstLines = wordWrap(notFirstLinesString, nonFirstLineSize);
List<String> nonFirstLineCollection = Arrays.asList(nonFirstLines);
ArrayList<String> allLines = new ArrayList<String>();
allLines.add(lines[0]);
allLines.addAll(nonFirstLineCollection);
lines = allLines.toArray(lines);
}
return lines;
}
public static String[] wordWrap(String str, int lineSize) {
if (str != null && str.length() > lineSize) {
Pattern regex = Pattern.compile("(\\S\\S{" + lineSize + ",}|.{1," + lineSize
+ "})(\\s+|$)");
List<String> list = new ArrayList<String>();
Matcher m = regex.matcher(str);
while (m.find()) {
String group = m.group();
// Preserve multiple newlines
String[] lines = StringUtils.splitPreserveAllTokens(group, '\n');
for (String line : lines) {
// Trim whitespace from end since a space on the end can
// push line wrap and cause an unintentional blank line.
line = StringUtils.removeEnd(line, " ");
list.add(line);
}
}
return (String[]) list.toArray(new String[list.size()]);
} else {
return new String[] { str };
}
}
public static String abbreviateForLogging(String value) {
if (value != null) {
value = value.trim();
}
return StringUtils.abbreviate(value, MAX_CHARS_TO_LOG);
}
public static Date parseDate(String str, String[] parsePatterns) {
return parseDate(str, parsePatterns, null);
}
public static Date parseDate(String str, String[] parsePatterns, TimeZone timeZone) {
if (str == null || parsePatterns == null) {
throw new IllegalArgumentException("Date and Patterns must not be null");
}
SimpleDateFormat parser = null;
ParsePosition pos = new ParsePosition(0);
for (int i = 0; i < parsePatterns.length; i++) {
if (i == 0) {
parser = new SimpleDateFormat(parsePatterns[0]);
if (timeZone != null) {
parser.setTimeZone(timeZone);
}
} else {
parser.applyPattern(parsePatterns[i]);
}
pos.setIndex(0);
Date date = parser.parse(str, pos);
if (date != null && pos.getIndex() == str.length()) {
return date;
}
}
try {
Date date = new Date(Long.parseLong(str));
return date;
} catch (NumberFormatException e) {
}
throw new ParseException("Unable to parse the date: " + str);
}
public static String[] splitOnSpacePreserveQuotedStrings(String source) {
List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("[^\\s\"']+|\"([^\"]*)\"|'([^']*)'");
Matcher regexMatcher = regex.matcher(source);
while (regexMatcher.find()) {
if (regexMatcher.group(1) != null) {
// Add double-quoted string without the quotes
matchList.add(regexMatcher.group(1));
} else if (regexMatcher.group(2) != null) {
// Add single-quoted string without the quotes
matchList.add(regexMatcher.group(2));
} else {
// Add unquoted word
matchList.add(regexMatcher.group());
}
}
return matchList.toArray(new String[matchList.size()]);
}
}