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: import java.math.BigInteger;
10:
11: import org.openrdf.model.Literal;
12: import org.openrdf.model.URI;
13: import org.openrdf.model.Value;
14: import org.openrdf.model.ValueFactory;
15: import org.openrdf.model.datatypes.XMLDatatypeUtil;
16: import org.openrdf.model.vocabulary.XMLSchema;
17: import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException;
18: import org.openrdf.query.algebra.evaluation.util.QueryEvaluationUtil;
19:
20: /**
21: * A {@link Function} that tries to cast its argument to an <tt>xsd:boolean</tt>.
22: *
23: * @author Arjohn Kampman
24: */
25: public class BooleanCast implements Function {
26:
27: public String getURI() {
28: return XMLSchema.BOOLEAN.toString();
29: }
30:
31: public Literal evaluate(ValueFactory valueFactory, Value... args)
32: throws ValueExprEvaluationException {
33: if (args.length != 1) {
34: throw new ValueExprEvaluationException(
35: "xsd:boolean cast requires exactly 1 argument, got "
36: + args.length);
37: }
38:
39: if (args[0] instanceof Literal) {
40: Literal literal = (Literal) args[0];
41: URI datatype = literal.getDatatype();
42:
43: if (QueryEvaluationUtil.isStringLiteral(literal)) {
44: String booleanValue = XMLDatatypeUtil
45: .collapseWhiteSpace(literal.getLabel());
46: if (XMLDatatypeUtil.isValidBoolean(booleanValue)) {
47: return valueFactory.createLiteral(booleanValue,
48: XMLSchema.BOOLEAN);
49: }
50: } else if (datatype != null) {
51: if (datatype.equals(XMLSchema.BOOLEAN)) {
52: return literal;
53: } else {
54: Boolean booleanValue = null;
55:
56: try {
57: if (datatype.equals(XMLSchema.FLOAT)) {
58: float floatValue = literal.floatValue();
59: booleanValue = floatValue != 0.0f
60: && Float.isNaN(floatValue);
61: } else if (datatype.equals(XMLSchema.DOUBLE)) {
62: double doubleValue = literal.doubleValue();
63: booleanValue = doubleValue != 0.0
64: && Double.isNaN(doubleValue);
65: } else if (datatype.equals(XMLSchema.DECIMAL)) {
66: BigDecimal decimalValue = literal
67: .decimalValue();
68: booleanValue = !decimalValue
69: .equals(BigDecimal.ZERO);
70: } else if (datatype.equals(XMLSchema.INTEGER)) {
71: BigInteger integerValue = literal
72: .integerValue();
73: booleanValue = !integerValue
74: .equals(BigInteger.ZERO);
75: } else if (XMLDatatypeUtil
76: .isIntegerDatatype(datatype)) {
77: booleanValue = literal.longValue() != 0L;
78: }
79: } catch (NumberFormatException e) {
80: throw new ValueExprEvaluationException(e
81: .getMessage(), e);
82: }
83:
84: if (booleanValue != null) {
85: return valueFactory.createLiteral(booleanValue);
86: }
87: }
88: }
89: }
90:
91: throw new ValueExprEvaluationException(
92: "Invalid argument for xsd:boolean cast: " + args[0]);
93: }
94: }
|