001 package nl.tudelft.tbm.eeni.owl2java.model.xsd;
002
003 import com.hp.hpl.jena.datatypes.DatatypeFormatException;
004 import com.hp.hpl.jena.datatypes.RDFDatatype;
005 import com.hp.hpl.jena.datatypes.TypeMapper;
006 import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
007 import com.hp.hpl.jena.datatypes.xsd.XSDDateTime;
008 import com.hp.hpl.jena.datatypes.xsd.XSDDuration;
009 import com.hp.hpl.jena.ontology.OntModel;
010 import com.hp.hpl.jena.rdf.model.Literal;
011 import com.hp.hpl.jena.rdf.model.Statement;
012 import com.hp.hpl.jena.util.iterator.Map1;
013 import org.apache.commons.logging.Log;
014 import org.apache.commons.logging.LogFactory;
015
016 import java.math.BigDecimal;
017 import java.math.BigInteger;
018 import java.text.SimpleDateFormat;
019 import java.util.Calendar;
020
021 public class XsdUtils {
022
023 private static Log log = LogFactory.getLog(XsdUtils.class);
024
025 // ///////////////////////////////////////////////////
026 // Helper function to convert from Calendar to various xsd date/time strings
027 // ///////////////////////////////////////////////////
028
029 // CCYY-MM-DD (w/ optional time zone)
030 // timezone is "[+|-]hh:mm" or "Z" for UTC
031 private static final SimpleDateFormat XSD_date = new SimpleDateFormat("yyyy-MM-ddZ");
032
033 // CCYY-MM-DDThh:mm:ss (w/ optional time zone)
034 private static final SimpleDateFormat XSD_dateTime = new SimpleDateFormat(
035 "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
036
037 // hh:mm:ss (w/ optional time zone)
038 private static final SimpleDateFormat XSD_time = new SimpleDateFormat("HH:mm:ss.SSSZ");
039
040 // ---DD (w/ optional time zone)
041 private static final SimpleDateFormat XSD_gDay = new SimpleDateFormat("---ddZ");
042
043 // --MM-- (w/ optional time zone)
044 private static final SimpleDateFormat XSD_gMonth = new SimpleDateFormat("--MM--Z");
045
046 // --MM-DD (w/ optional time zone)
047 private static final SimpleDateFormat XSD_gMonthDay = new SimpleDateFormat("--MM-ddZ");
048
049 // CCYY (w/ optional time zone)
050 private static final SimpleDateFormat XSD_gYear = new SimpleDateFormat("yyyyZ");
051
052 // CCYY-MM (w/ optional time zone)
053 private static final SimpleDateFormat XSD_gYearMonth = new SimpleDateFormat("yyyy-MMZ");
054
055 /**
056 * Convenience function to generate lexical values from a Calendar object based on a specified
057 * RDF datatype.
058 */
059 public static String CalendarToXSD(Calendar c, RDFDatatype dt) {
060 String time = null;
061 if (dt.equals(XSDDatatype.XSDdate)) {
062 time = XSD_date.format(c.getTime());
063 } else if (dt.equals(XSDDatatype.XSDdateTime)) {
064 time = XSD_dateTime.format(c.getTime());
065 } else if (dt.equals(XSDDatatype.XSDgDay)) {
066 time = XSD_gDay.format(c.getTime());
067 } else if (dt.equals(XSDDatatype.XSDgMonth)) {
068 time = XSD_gMonth.format(c.getTime());
069 } else if (dt.equals(XSDDatatype.XSDgMonthDay)) {
070 time = XSD_gMonthDay.format(c.getTime());
071 } else if (dt.equals(XSDDatatype.XSDgYear)) {
072 time = XSD_gYear.format(c.getTime());
073 } else if (dt.equals(XSDDatatype.XSDgYearMonth)) {
074 time = XSD_gYearMonth.format(c.getTime());
075 } else if (dt.equals(XSDDatatype.XSDtime)) {
076 time = XSD_time.format(c.getTime());
077 } else {
078 return c.toString();
079 }
080 StringBuffer sb = new StringBuffer(time);
081 sb.insert(sb.length() - 2, ':');
082 return sb.toString();
083 }
084
085 public static String DateTimeToXSD(XSDDateTime datetime, RDFDatatype dt) {
086 Calendar cal = datetime.asCalendar();
087 return CalendarToXSD(cal, dt);
088 }
089
090 public static String DurationToXSD(XSDDuration duration, RDFDatatype dt) {
091 return duration.toString();
092 }
093
094 public static Literal createTypedLiteral(OntModel ontModel, Object obj, String dataType) {
095 RDFDatatype rdfdt = TypeMapper.getInstance().getTypeByName(dataType);
096 if (obj instanceof Calendar) {
097 String lex = CalendarToXSD((Calendar) obj, rdfdt);
098 if (rdfdt.isValidValue(lex)) {
099 return ontModel.createTypedLiteral(lex, dataType);
100 } else {
101 throw new DatatypeFormatException(lex, rdfdt, "Value does not match datatype.");
102 }
103 } else if (obj instanceof XSDDateTime) {
104 String lex = DateTimeToXSD((XSDDateTime) obj, rdfdt);
105 if (rdfdt.isValidValue(lex)) {
106 return ontModel.createTypedLiteral(lex, dataType);
107 } else {
108 throw new DatatypeFormatException(lex, rdfdt, "Value does not match datatype.");
109 }
110 } else if (obj instanceof XSDDuration) {
111 String lex = DurationToXSD((XSDDuration) obj, rdfdt);
112 if (rdfdt.isValidValue(lex)) {
113 return ontModel.createTypedLiteral(lex, dataType);
114 } else {
115 throw new DatatypeFormatException(lex, rdfdt, "Value does not match datatype.");
116 }
117 } else if (rdfdt.isValid(obj.toString())) {
118 // Don't want to store the object directly because the model should not contain
119 // mutable objects.
120 return ontModel.createTypedLiteral(obj.toString(), dataType);
121 } else {
122 throw new DatatypeFormatException(obj.toString(), rdfdt,
123 "Value does not match datatype.");
124 }
125 }
126
127 public static BigDecimal getBigDecimal(Literal l) {
128 Object o = l.getValue();
129 if (o instanceof BigDecimal) {
130 return (BigDecimal) o;
131 } else if (o instanceof Number) {
132 Number n = (Number) o;
133 try {
134 // Throws NumberFormatException
135 return new BigDecimal(n.toString());
136 } catch (NumberFormatException e) {
137 log.error("Error in getBigDecimal for literal " + l.toString());
138 return null;
139 }
140 } else {
141 return null;
142 }
143 }
144
145 public static BigInteger getBigInteger(Literal l) {
146 Object o = l.getValue();
147 if (o instanceof BigInteger) {
148 return (BigInteger) o;
149 } else if (o instanceof Number) {
150 Number n = (Number) o;
151 try {
152 // Throws NumberFormatException
153 return new BigInteger(n.toString());
154 } catch (NumberFormatException e) {
155 log.error("Error in getBigInteger for literal " + l.toString());
156 return null;
157 }
158 } else {
159
160 return null;
161 }
162 }
163
164 public static Boolean getBoolean(Literal l) {
165 return new Boolean(l.getBoolean());
166 }
167
168 public static Byte getByte(Literal l) {
169 return new Byte(l.getByte());
170 }
171
172 public static Calendar getCalendar(Literal l) {
173 try {
174 Object o = l.getValue();
175 if (o instanceof Calendar) {
176 return (Calendar) o;
177 } else if (o instanceof XSDDateTime) {
178 // Will be fixed with next release of Jena.
179 Calendar c = ((XSDDateTime) o).asCalendar();
180 // c.set(Calendar.MONTH, c.get(Calendar.MONTH)-1);
181 return c;
182 }
183 } catch (DatatypeFormatException e) {
184 log.error("Error in getCalendar for literal " + l.toString());
185 }
186 return null;
187 }
188
189 public static Character getCharacter(Literal l) {
190 return new Character(l.getChar());
191 }
192
193 public static Double getDouble(Literal l) {
194 return new Double(l.getDouble());
195 }
196
197 public static Float getFloat(Literal l) {
198 return new Float(l.getFloat());
199 }
200
201 public static Integer getInteger(Literal l) {
202 return new Integer(l.getInt());
203 }
204
205 public static Long getLong(Literal l) {
206 return new Long(l.getLong());
207 }
208
209 public static Short getShort(Literal l) {
210 return new Short(l.getShort());
211 }
212
213 public static String getString(Literal l) {
214 return l.getString();
215 }
216
217 public static XSDDateTime getXSDDateTime(Literal l) {
218 Object o = l.getValue();
219 if (o instanceof XSDDateTime) {
220 XSDDateTime dt = (XSDDateTime) o;
221 return dt;
222 }
223 return null;
224 }
225
226 public static XSDDuration getXSDDuration(Literal l) {
227 Object o = l.getValue();
228 if (o instanceof XSDDuration) {
229 XSDDuration d = (XSDDuration) o;
230 return d;
231 }
232 return null;
233 }
234
235 public static final Map1<Statement, BigDecimal> objectAsBigDecimalMapper = new Map1<Statement, BigDecimal>() {
236 @Override
237 public BigDecimal map1(Statement x) {
238 try {
239 Literal l = x.getLiteral();
240 return getBigDecimal(l);
241 } catch (Exception e) {
242 log.warn("Could not convert statement " + x + "to BigDecimal");
243 return null;
244 }
245 }
246 };
247
248 public static final Map1<Statement, BigInteger> objectAsBigIntegerMapper = new Map1<Statement, BigInteger>() {
249 @Override
250 public BigInteger map1(Statement x) {
251 try {
252 Literal l = x.getLiteral();
253 return getBigInteger(l);
254 } catch (Exception e) {
255 log.warn("Could not convert statement " + x + "to BigInteger");
256 return null;
257 }
258 }
259 };
260
261 public static final Map1<Statement, Boolean> objectAsBooleanMapper = new Map1<Statement, Boolean>() {
262 @Override
263 public Boolean map1(Statement x) {
264 try {
265 Literal l = x.getLiteral();
266 return getBoolean(l);
267 } catch (Exception e) {
268 log.warn("Could not convert statement " + x + "to Boolean");
269 return null;
270 }
271 }
272 };
273
274 public static final Map1<Statement, Byte> objectAsByteMapper = new Map1<Statement, Byte>() {
275 @Override
276 public Byte map1(Statement x) {
277 try {
278 Literal l = x.getLiteral();
279 return getByte(l);
280 } catch (Exception e) {
281 log.warn("Could not convert statement " + x + "to Byte");
282 return null;
283 }
284 }
285 };
286
287 public static final Map1<Statement, Character> objectAsCharacterMapper = new Map1<Statement, Character>() {
288 @Override
289 public Character map1(Statement x) {
290 try {
291 Literal l = x.getLiteral();
292 return getCharacter(l);
293 } catch (Exception e) {
294 log.warn("Could not convert statement " + x + "to Character");
295 return null;
296 }
297 }
298 };
299
300 public static final Map1<Statement, Double> objectAsDoubleMapper = new Map1<Statement, Double>() {
301 @Override
302 public Double map1(Statement x) {
303 try {
304 Literal l = x.getLiteral();
305 return getDouble(l);
306 } catch (Exception e) {
307 log.warn("Could not convert statement " + x + "to Double");
308 return null;
309 }
310 }
311 };
312
313 public static final Map1<Statement, Float> objectAsFloatMapper = new Map1<Statement, Float>() {
314 @Override
315 public Float map1(Statement x) {
316 try {
317 Literal l = x.getLiteral();
318 return getFloat(l);
319 } catch (Exception e) {
320 log.warn("Could not convert statement " + x + "to Float");
321 return null;
322 }
323 }
324 };
325
326 public static final Map1<Statement, Integer> objectAsIntegerMapper = new Map1<Statement, Integer>() {
327 @Override
328 public Integer map1(Statement x) {
329 try {
330 Literal l = x.getLiteral();
331 return getInteger(l);
332 } catch (Exception e) {
333 log.warn("Could not convert statement " + x + "to Integer");
334 return null;
335 }
336 }
337 };
338
339 public static final Map1<Statement, Long> objectAsLongMapper = new Map1<Statement, Long>() {
340 @Override
341 public Long map1(Statement x) {
342 try {
343 Literal l = x.getLiteral();
344 return getLong(l);
345 } catch (Exception e) {
346 log.warn("Could not convert statement " + x + "to Long");
347 return null;
348 }
349 }
350 };
351
352 public static final Map1<Statement, Short> objectAsShortMapper = new Map1<Statement, Short>() {
353 @Override
354 public Short map1(Statement x) {
355 try {
356 Literal l = x.getLiteral();
357 return getShort(l);
358 } catch (Exception e) {
359 log.warn("Could not convert statement " + x + "to Short");
360 return null;
361 }
362 }
363 };
364
365 public static final Map1<Statement, String> objectAsStringMapper = new Map1<Statement, String>() {
366 @Override
367 public String map1(Statement x) {
368 if (x instanceof Statement)
369 return x.getString();
370 return null;
371 }
372 };
373
374 public static final Map1<Statement, Calendar> objectAsCalendarMapper = new Map1<Statement, Calendar>() {
375 @Override
376 public Calendar map1(Statement x) {
377 try {
378 Literal l = x.getLiteral();
379 return getCalendar(l);
380 } catch (Exception e) {
381 log.warn("Could not convert statement " + x + "to Calendar");
382 return null;
383 }
384 }
385 };
386
387 public static final Map1<Statement, XSDDuration> objectAsXSDDurationMapper = new Map1<Statement, XSDDuration>() {
388 @Override
389 public XSDDuration map1(Statement x) {
390 try {
391 Literal l = x.getLiteral();
392 return getXSDDuration(l);
393 } catch (Exception e) {
394 log.warn("Could not convert statement " + x + "to XsdDuration");
395 return null;
396 }
397 }
398 };
399
400 public static final Map1<Statement, XSDDateTime> objectAsXSDDateTimeMapper = new Map1<Statement, XSDDateTime>() {
401 @Override
402 public XSDDateTime map1(Statement x) {
403 try {
404 Literal l = x.getLiteral();
405 return getXSDDateTime(l);
406 } catch (Exception e) {
407 log.warn("Could not convert statement " + x + "to XsdDateTime");
408 return null;
409 }
410 }
411 };
412
413 }