01: /*
02: * Copyright Aduna (http://www.aduna-software.com/) (c) 2007.
03: *
04: * Licensed under the Aduna BSD-style license.
05: */
06: package org.openrdf.query.algebra.evaluation.function;
07:
08: import org.openrdf.model.Literal;
09: import org.openrdf.model.URI;
10: import org.openrdf.model.Value;
11: import org.openrdf.model.ValueFactory;
12: import org.openrdf.model.datatypes.XMLDatatypeUtil;
13: import org.openrdf.model.vocabulary.XMLSchema;
14: import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException;
15: import org.openrdf.query.algebra.evaluation.util.QueryEvaluationUtil;
16:
17: /**
18: * A {@link Function} that tries to cast its argument to an <tt>xsd:double</tt>.
19: *
20: * @author Arjohn Kampman
21: */
22: public class DoubleCast implements Function {
23:
24: public String getURI() {
25: return XMLSchema.DOUBLE.toString();
26: }
27:
28: public Literal evaluate(ValueFactory valueFactory, Value... args)
29: throws ValueExprEvaluationException {
30: if (args.length != 1) {
31: throw new ValueExprEvaluationException(
32: "xsd:double cast requires exactly 1 argument, got "
33: + args.length);
34: }
35:
36: if (args[0] instanceof Literal) {
37: Literal literal = (Literal) args[0];
38: URI datatype = literal.getDatatype();
39:
40: if (QueryEvaluationUtil.isStringLiteral(literal)) {
41: String doubleValue = XMLDatatypeUtil
42: .collapseWhiteSpace(literal.getLabel());
43: if (XMLDatatypeUtil.isValidDouble(doubleValue)) {
44: return valueFactory.createLiteral(doubleValue,
45: XMLSchema.DOUBLE);
46: }
47: } else if (datatype != null) {
48: if (datatype.equals(XMLSchema.DOUBLE)) {
49: return literal;
50: } else if (XMLDatatypeUtil.isNumericDatatype(datatype)) {
51: // FIXME: doubles must be processed separately, see
52: // http://www.w3.org/TR/xpath-functions/#casting-from-primitive-to-primitive
53: try {
54: double doubleValue = literal.doubleValue();
55: return valueFactory.createLiteral(doubleValue);
56: } catch (NumberFormatException e) {
57: throw new ValueExprEvaluationException(e
58: .getMessage(), e);
59: }
60: } else if (datatype.equals(XMLSchema.BOOLEAN)) {
61: try {
62: return valueFactory.createLiteral(literal
63: .booleanValue() ? 1.0 : 0.0);
64: } catch (IllegalArgumentException e) {
65: throw new ValueExprEvaluationException(e
66: .getMessage(), e);
67: }
68: }
69: }
70: }
71:
72: throw new ValueExprEvaluationException(
73: "Invalid argument for xsd:double cast: " + args[0]);
74: }
75: }
|