package jeql.util; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; import jeql.api.error.ExecutionException; import jeql.std.function.StringFunction; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.io.WKTWriter; public class TypeUtil { private static WKTWriter wktWriter = new WKTWriter(3); public static int compareValue(Object v1, Object v2) { if (v1 == null && v2 == null) return 0; // null is less than any non-null value if (v1 == null) return -1; if (v2 == null) return 1; if (v1 instanceof Comparable) { if (v2 == null) return -1; return ((Comparable) v1).compareTo(v2); } if (v1 instanceof Boolean) return compareValue( ((Boolean) v1).booleanValue(), ((Boolean) v2).booleanValue()); /* // all of these types implement Comparable if (v1 instanceof Double) return ((Double) v1).compareTo((Double) v2); if (v1 instanceof Integer) return ((Integer) v1).compareTo((Integer) v2); if (v1 instanceof String) return ((String) v1).compareTo((String) v2); */ if (v1 instanceof Geometry) return ((Geometry) v1).compareTo((Geometry) v2); // handle null values if (v1 == v2) return -1; // TODO: MD - this needs work... throw new IllegalArgumentException("Unknown value type: " + (v1 != null ? v1.getClass().getName() : "null")); } public static boolean isEqual(Object v1, Object v2) { return compareValue(v1, v2) == 0; } /** * Compares two boolean values, with <tt>false</tt> being less than <tt>true</tt>. * * @param b0 * @param b1 * @return */ public static int compareValue(boolean b0, boolean b1) { if (b0 == b1) return 0; if (b0) return 1; return -1; } public static boolean isSameType(Object o1, Object o2) { return o1.getClass() == o2.getClass(); } public static boolean isSameType(Class c1, Class c2) { return c1 == c2; } public static void checkSameType(Object o1, Object o2) { if (o1.getClass() != o2.getClass()) throw new ExecutionException("Objects are of different types"); } public static void checkCorrectType(Object o1, Class reqType) { // can't check type of null if (o1 == null) return; if (! reqType.isAssignableFrom(o1.getClass())) throw new ExecutionException("Expected type " + nameForType(reqType) + " but found type " + nameForType(o1.getClass())); } public static double toDouble(Object o) { if (o instanceof Integer) return new Double( ((Integer) o).intValue()); if (o instanceof Double) return ((Double) o); if (o instanceof String) { try { return new Double(Double.parseDouble((String) o)); } catch (NumberFormatException ex) { // eat it and drop thru to default return } } return 0.0; } public static boolean toBoolean(Object o) { if (o == null) return false; if (o instanceof Boolean) return (Boolean) o; return false; } public static Class typeForName(String name) { if (name.equalsIgnoreCase("string")) return String.class; if (name.equalsIgnoreCase("int")) return Integer.class; if (name.equalsIgnoreCase("integer")) return Integer.class; if (name.equalsIgnoreCase("boolean")) return Boolean.class; if (name.equalsIgnoreCase("geometry")) return Geometry.class; if (name.equalsIgnoreCase("double")) return Double.class; if (name.equalsIgnoreCase("date")) return Date.class; return null; } public static String nameForType(Class clz) { // TODO: check for valid JEQL type return ClassUtil.classname(clz); } public static double MAX_DECIMAL = 1.0e15; public static double MIN_DECIMAL = 1.0e-15; public static String DECIMAL_FORMAT_PATTERN = "0.0###############"; public static DecimalFormat DECIMAL_FORMAT = new DecimalFormat(DECIMAL_FORMAT_PATTERN); public static String SCI_FORMAT_PATTERN = "0.0###############E0"; public static DecimalFormat SCI_FORMAT = new DecimalFormat(SCI_FORMAT_PATTERN); public static String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS"; public static DateFormat DATE_FORMAT = new SimpleDateFormat(DATE_PATTERN); public static String DATE_PATTERN_YMD_HMS = "yyyy-MM-dd HH:mm:ss"; public static DateFormat DATE_FORMAT_YMD_HMS = new SimpleDateFormat(DATE_PATTERN_YMD_HMS); public static String DATE_PATTERN_YMD = "yyyy-MM-dd"; public static DateFormat DATE_FORMAT_YMD = new SimpleDateFormat(DATE_PATTERN_YMD); public static String toString(Object o) { if (o == null) return "null"; if (o instanceof Date) { return DATE_FORMAT.format((Date) o); } if (o instanceof Double) { double d = ((Double) o).doubleValue(); double abs = Math.abs(d); if (abs > MAX_DECIMAL || abs < MIN_DECIMAL) return SCI_FORMAT.format(d); return DECIMAL_FORMAT.format(d); } if (o instanceof Geometry) { return wktWriter.writeFormatted((Geometry) o); } return o.toString(); } public static String toCodeString(Object o) { if (o instanceof String) { return "\"" + o + "\""; } return toString(o); } public static int MAX_LEN = 20; public static int MAX_GEOM_LEN = 40; public static String toCodeStringLimited(Object o) { if (o instanceof String) { String s = (String) o; if (s.length() <= MAX_LEN) return "\"" + s + "\""; return "\"" + StringFunction.leftStr((String) o, MAX_LEN) + " ...\""; } if (o instanceof Geometry) { Geometry g = (Geometry) o; if (g.getNumPoints() <= 5) return g.toString(); //TODO: do this better - display just a single coordinate if long return StringFunction.leftStr(g.toString(), MAX_GEOM_LEN)+" ...)"; } return toString(o); } }