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