package org.exist.fluent; import java.util.*; import javax.xml.datatype.*; import org.exist.util.Base64Encoder; /** * A bunch of static data conversion utility methods. * * @author <a href="mailto:piotr@ideanest.com">Piotr Kaminski</a> */ public class DataUtils { private DataUtils() {} /** * A comparator for dateTimes (XMLGregorianCalendar objects), that uses the partial order defined on dateTimes and throws an exception if the order is indeterminate. */ public static final Comparator<XMLGregorianCalendar> DATE_TIME_COMPARATOR = new Comparator<XMLGregorianCalendar>() { public int compare(XMLGregorianCalendar a, XMLGregorianCalendar b) { int r = a.compare(b); if (r == DatatypeConstants.INDETERMINATE) throw new RuntimeException("date-times not comparable: " + a + " and " + b); return r; } }; private static DatatypeFactory datatypeFactory; static { try { datatypeFactory = DatatypeFactory.newInstance(); } catch (DatatypeConfigurationException e) { throw new RuntimeException("unable to configure datatype factory", e); } } /** * Return a shared instance of a datatype factory, used for creating new XML data objects. * * @return a shared datatype factory */ public static DatatypeFactory datatypeFactory() { return datatypeFactory; } /** * Convert an XML date/time to its <code>java.util.Date</code> equivalent. * * @param dateTime the XML date/time to convert * @return a Java date */ public static Date toDate(XMLGregorianCalendar dateTime) { return dateTime.toGregorianCalendar().getTime(); } /** * Convert a Java date to its XML date/time equivalent. * * @param date the Java date to convert * @return an XML date/time */ public static XMLGregorianCalendar toDateTime(Date date) { GregorianCalendar cal = new GregorianCalendar(); cal.setTime(date); return datatypeFactory().newXMLGregorianCalendar(cal).normalize(); } /** * Convert milliseconds offset to its XML date/time equivalent. * * @param millis a millisecond count since the epoch * @return an XML date/time */ public static XMLGregorianCalendar toDateTime(long millis) { GregorianCalendar cal = new GregorianCalendar(); cal.setTimeInMillis(millis); return datatypeFactory().newXMLGregorianCalendar(cal).normalize(); } /** * Convert a Java object to its equivalent XML datatype string representation. * At the moment, there is special treatment for <code>java.util.Date</code>, * <code>java.util.Calendar</code> and <code>byte[]</code> (Base64 encoding); * for all other objects, we simply invoke <code>toString()</code>. * * @param o the object to convert * @return a string representation of the object, according to XML Schema Datatype rules if possible */ public static String toXMLString(Object o) { Object r = toXMLObject(o); if (r.getClass() != String.class) r = r.toString(); return (String) r; } /** * Convert a Java object to its equivalent XML datatype representation. * At the moment, there is special treatment for <code>java.util.Date</code>, * <code>java.util.Calendar</code> and <code>byte[]</code> (Base64 encoding); * all other objects are simply passed through as-is. * * @param o the object to convert * @return an XML representation of the object, according to XML Schema Datatype rules if possible */ public static Object toXMLObject(Object o) { if (o instanceof Date) { return toDateTime((Date) o).toString(); } else if (o instanceof Calendar) { return toDateTime(((Calendar) o).getTimeInMillis()).toString(); } else if (o instanceof byte[]) { Base64Encoder encoder = new Base64Encoder(); encoder.translate((byte[]) o); return String.valueOf(encoder.getCharArray()); } else { return o; } } }