001: package org.ontoware.rdfreactor.runtime.converter;
002:
003: import java.util.Calendar;
004: import java.util.GregorianCalendar;
005: import java.util.TimeZone;
006:
007: import org.ontoware.rdf2go.model.Model;
008: import org.ontoware.rdf2go.model.node.DatatypeLiteral;
009: import org.ontoware.rdf2go.model.node.LanguageTagLiteral;
010: import org.ontoware.rdf2go.model.node.Literal;
011: import org.ontoware.rdf2go.model.node.Node;
012: import org.ontoware.rdf2go.model.node.PlainLiteral;
013: import org.ontoware.rdf2go.model.node.URI;
014: import org.ontoware.rdf2go.model.node.impl.DatatypeLiteralImpl;
015: import org.ontoware.rdf2go.vocabulary.XSD;
016: import org.ontoware.rdfreactor.runtime.INodeConverter;
017: import org.ontoware.rdfreactor.runtime.RDFDataException;
018: import org.slf4j.Logger;
019: import org.slf4j.LoggerFactory;
020:
021: import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
022: import com.hp.hpl.jena.datatypes.xsd.XSDDateTime;
023:
024: /**
025: * Handles ISO 8601 Date and Time Formats
026: *
027: * http://jena.sourceforge.net/javadoc/com/hp/hpl/jena/datatypes/xsd/XSDDatatype.html
028: *
029: * http://jena.sourceforge.net/how-to/typedLiterals.html#xsd
030: *
031: * @author voelkel
032: *
033: */
034: public class CalendarConverter implements INodeConverter<Calendar> {
035:
036: private static final Logger log = LoggerFactory
037: .getLogger(CalendarConverter.class);
038:
039: public Calendar toJava(Node node) {
040: return node2Calendar(node);
041: }
042:
043: public static Calendar node2Calendar(Node node) {
044: if (node == null)
045: return null;
046:
047: if (node instanceof PlainLiteral) {
048: return toCalendar(node.asLiteral());
049: }
050:
051: if (node instanceof LanguageTagLiteral) {
052: throw new RDFDataException(
053: "Cannot convert a language tagged literal to an Calendar - it makes no sense");
054: }
055:
056: if (node instanceof DatatypeLiteral) {
057: URI datatype = node.asDatatypeLiteral().getDatatype();
058: if (datatype.equals(XSD._dateTime)
059: || datatype.equals(XSD._date)
060: || datatype.equals(XSD._time)) {
061: return toCalendar(node.asDatatypeLiteral());
062: } else {
063: throw new RDFDataException(
064: "Cannot convert from datatype " + datatype
065: + " to URI");
066: }
067: }
068:
069: throw new RDFDataException("Cannot convert from "
070: + node.getClass() + " to Calendar");
071: }
072:
073: public static Calendar toCalendar(Literal literal) {
074: return parseXSDDateTime_toCalendar(literal.getValue());
075: }
076:
077: /** return all normalized to UTC */
078: public static String encodeCalendar_toXSDDateTime(Calendar cal) {
079:
080: // convert cal to UTC
081:
082: Calendar utcCalendar = new GregorianCalendar(TimeZone
083: .getTimeZone("UTC"));
084: utcCalendar.setTimeInMillis(cal.getTimeInMillis());
085:
086: // TODO get rid of Jena dependency
087: XSDDateTime x = new XSDDateTime(utcCalendar);
088:
089: StringBuffer buff = new StringBuffer();
090:
091: int years = x.getYears();
092: buff.append(years);
093: buff.append("-");
094:
095: if (x.getMonths() < 10)
096: buff.append("0");
097: buff.append(x.getMonths());
098: buff.append("-");
099:
100: if (x.getDays() < 10)
101: buff.append("0");
102: buff.append(x.getDays());
103: buff.append("T");
104:
105: if (x.getHours() < 10)
106: buff.append("0");
107: buff.append(x.getHours());
108:
109: buff.append(":");
110: if (x.getMinutes() < 10)
111: buff.append("0");
112: buff.append(x.getMinutes());
113:
114: buff.append(":");
115: if (x.getFullSeconds() < 10)
116: buff.append("0");
117: buff.append(x.getFullSeconds());
118:
119: // TODO append milliseconds
120: // double milliseconds = ((double) x.getSeconds() - (double)
121: // x.getFullSeconds());
122:
123: buff.append("Z");
124: return buff.toString();
125:
126: }
127:
128: public static Calendar parseXSDDateTime_toCalendar(String s)
129: throws RDFDataException {
130: log.debug("Trying to parse '" + s + "' as an xsd:dateTime");
131:
132: // TODO get rid of Jena dependency
133: XSDDateTime xsddate = (XSDDateTime) XSDDatatype.XSDdateTime
134: .parse(s);
135:
136: if (xsddate == null)
137: throw new RDFDataException("Could not parse '" + s
138: + "' as an xsd:DateTime.");
139:
140: log
141: .debug(xsddate.getYears() + "-" + xsddate.getMonths()
142: + "-" + xsddate.getDays() + "-"
143: + xsddate.getHours() + "-"
144: + xsddate.getMinutes() + "-"
145: + xsddate.getFullSeconds());
146:
147: Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UCT"));
148: c.set(Calendar.YEAR, xsddate.getYears());
149: c.set(Calendar.MONTH, xsddate.getMonths() - 1);
150: c.set(Calendar.DATE, xsddate.getDays());
151:
152: log.debug("Hour = " + xsddate.getHours());
153:
154: c.set(Calendar.HOUR_OF_DAY, xsddate.getHours());
155: c.set(Calendar.MINUTE, xsddate.getMinutes());
156: c.set(Calendar.SECOND, (int) xsddate.getSeconds());
157: // IMPROVE ... c.set(Calendar.MILLISECOND, ) currently we have only
158: // second-precision
159:
160: return c;
161: }
162:
163: public Node toNode(Model model, Object javaValue) {
164: String xsdDateTime = encodeCalendar_toXSDDateTime((Calendar) javaValue);
165: return new DatatypeLiteralImpl(xsdDateTime, XSD._dateTime);
166: }
167:
168: }
|