org.openrdf.sesame.sail.query.MathExpr Maven / Gradle / Ivy
Go to download
Sesame is an open source Java framework for storing, querying and reasoning with RDF.
The newest version!
/* Sesame - Storage and Querying architecture for RDF and RDF Schema
* Copyright (C) 2001-2006 Aduna
*
* Contact:
* Aduna
* Prinses Julianaplein 14 b
* 3817 CS Amersfoort
* The Netherlands
* tel. +33 (0)33 465 99 87
* fax. +33 (0)33 465 99 87
*
* http://aduna-software.com/
* http://www.openrdf.org/
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.openrdf.sesame.sail.query;
import java.math.BigInteger;
import java.math.BigDecimal;
import java.util.Collection;
import org.openrdf.vocabulary.XmlSchema;
import org.openrdf.util.xml.XmlDatatypeUtil;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.impl.LiteralImpl;
import org.openrdf.model.impl.URIImpl;
/**
* A mathematical expression consisting an operator and two arguments.
**/
public class MathExpr implements ValueExpr {
/*----------+
| Constants |
+----------*/
/** The plus (+) operator. **/
public static final int PLUS = 0;
/** The subtraction (-) operator. **/
public static final int SUBTRACT = 1;
/** The multiplication (*) operator. **/
public static final int MULTIPLY = 2;
/** The division (/) operator. **/
public static final int DIVIDE = 3;
/** The remainder (%) operator. **/
public static final int REMAINDER = 4;
/** http://www.w3.org/2001/XMLSchema#integer **/
private static final URI XSD_INTEGER_URI = new URIImpl(XmlSchema.INTEGER);
/** http://www.w3.org/2001/XMLSchema#double **/
private static final URI XSD_DOUBLE_URI = new URIImpl(XmlSchema.DOUBLE);
/*----------+
| Variables |
+----------*/
private ValueExpr _leftArg;
private ValueExpr _rightArg;
private int _operator;
/*-------------+
| Constructors |
+-------------*/
public MathExpr(ValueExpr leftArg, ValueExpr rightArg, int op) {
if (op < PLUS || op > REMAINDER) {
throw new IllegalArgumentException("Illegal operator: " + op);
}
_leftArg = leftArg;
_rightArg = rightArg;
_operator = op;
}
/*--------+
| Methods |
+--------*/
public ValueExpr getLeftArg() {
return _leftArg;
}
public ValueExpr getRightArg() {
return _rightArg;
}
public int getOperator() {
return _operator;
}
// implements StringExpr.getVariables(Collection)
public void getVariables(Collection variables) {
_leftArg.getVariables(variables);
_rightArg.getVariables(variables);
}
// implements StringExpr.getString()
public String getString() {
Value value = getValue();
if (value != null) {
return ((Literal)value).getLabel();
}
return null;
}
// implements ValueExpr.getValue()
public Value getValue() {
// Do the math
Value leftVal = _leftArg.getValue();
Value rightVal = _rightArg.getValue();
if (leftVal instanceof Literal && rightVal instanceof Literal) {
return getValue((Literal)leftVal, (Literal)rightVal, _operator);
}
return null;
}
public static Literal getValue(Literal leftLit, Literal rightLit, int op) {
String leftLabel = leftLit.getLabel();
URI leftDatatype = leftLit.getDatatype();
String rightLabel = rightLit.getLabel();
URI rightDatatype = rightLit.getDatatype();
if (leftDatatype == null || XmlDatatypeUtil.isIntegerDatatype(leftDatatype.getURI()) &&
rightDatatype == null || XmlDatatypeUtil.isIntegerDatatype(rightDatatype.getURI()))
{
// Both arguments are, or could be, integers. Attempt an integer operation.
try {
BigInteger leftInt = new BigInteger(leftLabel);
BigInteger rightInt = new BigInteger(rightLabel);
BigInteger result = null;
switch (op) {
case PLUS : result = leftInt.add(rightInt); break;
case SUBTRACT : result = leftInt.subtract(rightInt); break;
case MULTIPLY : result = leftInt.multiply(rightInt); break;
case DIVIDE : result = leftInt.divide(rightInt); break;
case REMAINDER: result = leftInt.remainder(rightInt); break;
default: throw new IllegalArgumentException("Unknown operator: " + op);
}
// Return the result as an xsd:integer
return new LiteralImpl(result.toString(), XSD_INTEGER_URI);
}
catch (NumberFormatException e) {
if (leftDatatype != null && rightDatatype != null) {
// Both were specified to be integer, but apparently are not
return null;
}
// else: type casting of untyped literal to an integer failed,
// attempt decimal operation
}
}
// Integer operation failed or does not apply, attempt floating point operation
try {
BigDecimal leftDec = new BigDecimal(leftLabel);
BigDecimal rightDec = new BigDecimal(rightLabel);
BigDecimal result = null;
switch (op) {
case PLUS : result = leftDec.add(rightDec); break;
case SUBTRACT : result = leftDec.subtract(rightDec); break;
case MULTIPLY : result = leftDec.multiply(rightDec); break;
case DIVIDE : result = leftDec.divide(rightDec, 32, BigDecimal.ROUND_DOWN); break;
case REMAINDER: return null; // Remainder is not applicable to floating point numbers
default: throw new IllegalArgumentException("Unknown operator: " + op);
}
// Return the result as an xsd:double
return new LiteralImpl(result.toString(), XSD_DOUBLE_URI);
}
catch (NumberFormatException e) {
return null;
}
}
public String toString() {
StringBuffer buf = new StringBuffer(32);
buf.append( _leftArg.toString() );
switch (_operator) {
case PLUS : buf.append(" + "); break;
case SUBTRACT : buf.append(" - "); break;
case MULTIPLY : buf.append(" * "); break;
case DIVIDE : buf.append(" / "); break;
case REMAINDER: buf.append(" % "); break;
}
buf.append( _rightArg.toString() );
return buf.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy