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 java.math.BigDecimal;
09:
10: import org.openrdf.model.Literal;
11: import org.openrdf.model.URI;
12: import org.openrdf.model.Value;
13: import org.openrdf.model.ValueFactory;
14: import org.openrdf.model.datatypes.XMLDatatypeUtil;
15: import org.openrdf.model.vocabulary.XMLSchema;
16: import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException;
17: import org.openrdf.query.algebra.evaluation.util.QueryEvaluationUtil;
18:
19: /**
20: * A {@link Function} that tries to cast its argument to an <tt>xsd:decimal</tt>.
21: *
22: * @author Arjohn Kampman
23: */
24: public class DecimalCast implements Function {
25:
26: public String getURI() {
27: return XMLSchema.DECIMAL.toString();
28: }
29:
30: public Literal evaluate(ValueFactory valueFactory, Value... args)
31: throws ValueExprEvaluationException {
32: if (args.length != 1) {
33: throw new ValueExprEvaluationException(
34: "xsd:decimal cast requires exactly 1 argument, got "
35: + args.length);
36: }
37:
38: if (args[0] instanceof Literal) {
39: Literal literal = (Literal) args[0];
40: URI datatype = literal.getDatatype();
41:
42: if (QueryEvaluationUtil.isStringLiteral(literal)) {
43: String decimalValue = XMLDatatypeUtil
44: .collapseWhiteSpace(literal.getLabel());
45: if (XMLDatatypeUtil.isValidDecimal(decimalValue)) {
46: return valueFactory.createLiteral(decimalValue,
47: XMLSchema.DECIMAL);
48: }
49: } else if (datatype != null) {
50: if (datatype.equals(XMLSchema.DECIMAL)) {
51: return literal;
52: } else if (XMLDatatypeUtil.isNumericDatatype(datatype)) {
53: // FIXME: floats and doubles must be processed separately, see
54: // http://www.w3.org/TR/xpath-functions/#casting-from-primitive-to-primitive
55: try {
56: BigDecimal decimalValue = literal
57: .decimalValue();
58: return valueFactory.createLiteral(decimalValue
59: .toPlainString(), XMLSchema.DECIMAL);
60: } catch (NumberFormatException e) {
61: throw new ValueExprEvaluationException(e
62: .getMessage(), e);
63: }
64: } else if (datatype.equals(XMLSchema.BOOLEAN)) {
65: try {
66: return valueFactory.createLiteral(literal
67: .booleanValue() ? "1.0" : "0.0",
68: XMLSchema.DECIMAL);
69: } catch (IllegalArgumentException e) {
70: throw new ValueExprEvaluationException(e
71: .getMessage(), e);
72: }
73: }
74: }
75: }
76:
77: throw new ValueExprEvaluationException(
78: "Invalid argument for xsd:decimal cast: " + args[0]);
79: }
80: }
|