Util.java
package org.microspace.table.query.sql;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.microspace.util.PojoUtil;
import org.microspace.util.UniqueId;
/**
* Utility package for MicroSpace.
*
* @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
* @version 2017-09-29
*/
public class Util {
/* Almost ISO 8601 international standard date and time notation */
public static final String FORMAT_DATE = "yyyy-MM-dd";
public static final String FORMAT_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
public static final String FORMAT_DATE_TIME_MS = "yyyy-MM-dd HH:mm:ss.SSS";
private static ThreadLocal<SimpleDateFormat> dateFormatterCacheDate = new ThreadLocal<SimpleDateFormat> () {
@Override
public SimpleDateFormat initialValue () {
SimpleDateFormat ret = new SimpleDateFormat(FORMAT_DATE);
ret.setTimeZone(TimeZone.getTimeZone("UTC"));
return ret;
}
};
private static ThreadLocal<SimpleDateFormat> dateFormatterCacheDateTime = new ThreadLocal<SimpleDateFormat> () {
@Override
public SimpleDateFormat initialValue () {
SimpleDateFormat ret = new SimpleDateFormat(FORMAT_DATE_TIME);
ret.setTimeZone(TimeZone.getTimeZone("UTC"));
return ret;
}
};
private static ThreadLocal<SimpleDateFormat> dateFormatterCacheDateTimeMs = new ThreadLocal<SimpleDateFormat> () {
@Override
public SimpleDateFormat initialValue () {
SimpleDateFormat ret = new SimpleDateFormat(FORMAT_DATE_TIME_MS);
ret.setTimeZone(TimeZone.getTimeZone("UTC"));
return ret;
}
};
public static Date parseDate (String value) {
try {
if (value.length() == FORMAT_DATE_TIME_MS.length()) {
return dateFormatterCacheDateTimeMs.get().parse(value);
} else if (value.length() == FORMAT_DATE_TIME.length()) {
return dateFormatterCacheDateTime.get().parse(value);
} else if (value.length() == FORMAT_DATE.length()) {
return dateFormatterCacheDate.get().parse(value);
} else {
throw new IllegalArgumentException ("Can Not Guess Date Format");
}
} catch (ParseException e) {
throw new IllegalArgumentException("Bad Date Format", e);
}
}
/**
* Remove quote signs and resolve escape sequences.
* <pre>
* 'single=\'' or '' backslash=\\' = single=' or ' backslash=\
*
* "double=\" or "" backslash=\" = double=" or "" backslash=\
* </pre>
* @param quotedString The quoted String.
* @return The plain string.
*/
public static String unquote (String quotedString) {
char begin = quotedString.charAt(0);
char end = quotedString.charAt(quotedString.length()-1);
if (begin != end) {
throw new IllegalArgumentException ("Malformed String");
}
StringBuffer ret = new StringBuffer(quotedString.length());
for (int i=1; i<quotedString.length()-1; i++) {
if (quotedString.charAt(i) == '\\' &&
(quotedString.charAt(i+1) == begin || quotedString.charAt(i+1) == '\\'))
{
ret.append(quotedString.charAt(i+1));
i++;
if (i>=quotedString.length()-1) {
throw new IllegalArgumentException ("Malformed String Too Short for '\\'");
}
continue;
}
if (quotedString.charAt(i) == begin &&
quotedString.charAt(i+1) == begin
) {
ret.append(begin);
i++;
if (i>=quotedString.length()-1) {
throw new IllegalArgumentException ("Malformed String Too Short");
}
continue;
}
ret.append(quotedString.charAt(i));
}
return ret.toString();
}
/**
* Quote a bareString.
* @param bareString The bare String.
* @return The quoted string suitable for Sql.
*/
public static String quote (String bareString) {
StringBuffer ret = new StringBuffer(bareString.length());
ret.append("'");
for (int i=0; i<bareString.length(); i++) {
char at = bareString.charAt(i);
if (at == '\\') {
ret.append("\\\\");
continue;
}
if (at == '\'') {
ret.append("\\\'");
continue;
}
ret.append(at);
}
ret.append("'");
return ret.toString();
}
@SuppressWarnings("unchecked")
public static <T> T createColumnObject (String value,
Class<T> columnClass, LiteralValueType columnType) {
T columnObject;
if (Date.class.isAssignableFrom(columnClass)) {
columnObject = (T) Util.parseDate(value);
} else {
columnObject = PojoUtil.createObjectFromString(value, columnClass);
if (columnObject == null) {
throw new IllegalArgumentException("Can not create class from String " + columnClass);
}
if (columnType == LiteralValueType.BOOLEAN && ! (columnObject instanceof Boolean)) {
throw new IllegalArgumentException("Boolean Type Expected");
}
if (columnType == LiteralValueType.NUMBER && columnObject instanceof String) {
throw new IllegalArgumentException("Numeric Type Expected");
}
if (columnType == LiteralValueType.NUMBER && columnObject instanceof UniqueId) {
throw new IllegalArgumentException("Numeric Type Expected");
}
}
return columnObject;
}
}