return false;
}
}
private static Literal getValue(Literal leftLit, Literal rightLit, MathOp op) {
URI leftDatatype = leftLit.getDatatype();
URI rightDatatype = rightLit.getDatatype();
// Only numeric value can be used in math expressions
if (leftDatatype != null && rightDatatype != null && XMLDatatypeUtil.isNumericDatatype(leftDatatype)
&& XMLDatatypeUtil.isNumericDatatype(rightDatatype))
{
// Determine most specific datatype that the arguments have in common,
// choosing from xsd:integer, xsd:decimal, xsd:float and xsd:double as
// per the SPARQL/XPATH spec
URI commonDatatype;
if (leftDatatype.equals(XMLSchema.DOUBLE) || rightDatatype.equals(XMLSchema.DOUBLE)) {
commonDatatype = XMLSchema.DOUBLE;
}
else if (leftDatatype.equals(XMLSchema.FLOAT) || rightDatatype.equals(XMLSchema.FLOAT)) {
commonDatatype = XMLSchema.FLOAT;
}
else if (leftDatatype.equals(XMLSchema.DECIMAL) || rightDatatype.equals(XMLSchema.DECIMAL)) {
commonDatatype = XMLSchema.DECIMAL;
}
else if (op == MathOp.DIVIDE) {
// Result of integer divide is decimal and requires the arguments to
// be handled as such, see for details:
// http://www.w3.org/TR/xpath-functions/#func-numeric-divide
commonDatatype = XMLSchema.DECIMAL;
}
else {
commonDatatype = XMLSchema.INTEGER;
}
// Note: Java already handles cases like divide-by-zero appropriately
// for floats and doubles, see:
// http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Tech/
// Chapter02/floatingPt2.html
try {
if (commonDatatype.equals(XMLSchema.DOUBLE)) {
double left = leftLit.doubleValue();
double right = rightLit.doubleValue();
switch (op) {
case PLUS:
return new NumericLiteralImpl(left + right);
case MINUS:
return new NumericLiteralImpl(left - right);
case MULTIPLY:
return new NumericLiteralImpl(left * right);
case DIVIDE:
return new NumericLiteralImpl(left / right);
default:
throw new IllegalArgumentException("Unknown operator: " + op);
}
}
else if (commonDatatype.equals(XMLSchema.FLOAT)) {
float left = leftLit.floatValue();
float right = rightLit.floatValue();
switch (op) {
case PLUS:
return new NumericLiteralImpl(left + right);
case MINUS:
return new NumericLiteralImpl(left - right);
case MULTIPLY:
return new NumericLiteralImpl(left * right);
case DIVIDE:
return new NumericLiteralImpl(left / right);
default:
throw new IllegalArgumentException("Unknown operator: " + op);
}
}
else if (commonDatatype.equals(XMLSchema.DECIMAL)) {
BigDecimal left = leftLit.decimalValue();
BigDecimal right = rightLit.decimalValue();
switch (op) {
case PLUS: