Package net.fortytwo.ripple.model.impl.sesame

Source Code of net.fortytwo.ripple.model.impl.sesame.SesameNumericValue

package net.fortytwo.ripple.model.impl.sesame;

import net.fortytwo.ripple.RippleException;
import net.fortytwo.ripple.model.ModelConnection;
import net.fortytwo.ripple.model.NumericValue;
import net.fortytwo.ripple.model.RDFValue;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.vocabulary.XMLSchema;

import java.math.BigDecimal;

/**
* @author Joshua Shinavier (http://fortytwo.net)
*/
public class SesameNumericValue extends NumericValue {

    private RDFValue rdfEquivalent = null;

    public SesameNumericValue(final int i) {
        type = Type.INTEGER;
        number = i;
    }

    public SesameNumericValue(final long l) {
        type = Type.LONG;
        number = l;
    }

    public SesameNumericValue(final double d) {
        type = Type.DOUBLE;
        number = d;
    }

    public SesameNumericValue(final float f) {
        type = Type.FLOAT;
        number = f;
    }

    public SesameNumericValue(final BigDecimal b) {
        type = Type.DECIMAL;
        number = b;
    }

    public SesameNumericValue(final RDFValue rdf)
            throws RippleException {
        rdfEquivalent = rdf;
        Value v = rdf.sesameValue();

        if (!(v instanceof Literal)) {
            throw new RippleException("value " + v.toString() + " is not numeric");
        }

        URI dataType = ((Literal) v).getDatatype();

        if (null == dataType) {
            throw new RippleException("value is untyped");
        } else if (dataType.equals(XMLSchema.INTEGER)
                || dataType.equals(XMLSchema.INT)) {
            try {
                type = Type.INTEGER;
                number = ((Literal) v).intValue();
            } catch (Throwable t) {
                throw new RippleException(t);
            }
        } else if (dataType.equals(XMLSchema.LONG)) {
            try {
                type = Type.LONG;
                number = (long) ((Literal) v).intValue();
            } catch (Throwable t) {
                throw new RippleException(t);
            }
        } else if (dataType.equals(XMLSchema.DOUBLE)) {
            try {
                type = Type.DOUBLE;
                number = doubleValue((Literal) v);
            } catch (Throwable t) {
                throw new RippleException(t);
            }
        } else if (dataType.equals(XMLSchema.FLOAT)) {
            try {
                type = Type.FLOAT;
                number = ((Literal) v).floatValue();
            } catch (Throwable t) {
                throw new RippleException(t);
            }
        } else if (dataType.equals(XMLSchema.DECIMAL)) {
            try {
                type = Type.DECIMAL;
                number = ((Literal) v).decimalValue();
            } catch (Throwable t) {
                throw new RippleException(t);
            }
        } else {
            throw new RippleException("not a recognized numeric data type: " + dataType);
        }
    }

    public RDFValue toRDF(final ModelConnection mc)
            throws RippleException {
        SesameModelConnection smc = (SesameModelConnection) mc;
        if (null == rdfEquivalent) {
            switch (type) {
                case INTEGER:
                    // Don't use ValueFactory.creatLiteral(int), which (at
                    // least in this case) produces xsd:int instead of xsd:integer
                    rdfEquivalent = new RDFValue(
                            smc.getValueFactory().createLiteral("" + number.intValue(), XMLSchema.INTEGER));
                    break;
                case LONG:
                    rdfEquivalent = new RDFValue(
                            smc.getValueFactory().createLiteral(number.longValue()));
                    break;
                case DOUBLE:
                    rdfEquivalent = new RDFValue(
                            smc.getValueFactory().createLiteral(number.doubleValue()));
                    break;
                case FLOAT:
                    rdfEquivalent = new RDFValue(
                            smc.getValueFactory().createLiteral(number.floatValue()));
                    break;
                case DECIMAL:
                    rdfEquivalent = new RDFValue(
                            smc.getValueFactory().createLiteral(number.toString(), XMLSchema.DECIMAL));
                    break;
            }
        }

        return rdfEquivalent;
    }

    public NumericValue abs() {
        NumericValue a = this;

        switch (a.getDatatype()) {
            case INTEGER:
                return new SesameNumericValue(Math.abs(a.intValue()));
            case LONG:
                return new SesameNumericValue(Math.abs(a.longValue()));
            case FLOAT:
                return new SesameNumericValue(Math.abs(a.floatValue()));
            case DOUBLE:
                return new SesameNumericValue(Math.abs(a.doubleValue()));
            case DECIMAL:
                return new SesameNumericValue(a.decimalValue().abs());
            default:
                // This shouldn't happen.
                return null;
        }
    }

    public NumericValue neg() {
        NumericValue a = this;

        switch (a.getDatatype()) {
            case INTEGER:
                return new SesameNumericValue(-a.intValue());
            case LONG:
                return new SesameNumericValue(-a.longValue());
            case FLOAT:
                return new SesameNumericValue(-a.floatValue());
            case DOUBLE:
                // Note: avoids negative zero.
                return new SesameNumericValue(0.0 - a.doubleValue());
            case DECIMAL:
                return new SesameNumericValue(a.decimalValue().negate());
            default:
                // This shouldn't happen.
                return null;
        }
    }

    public NumericValue add(final NumericValue b) {
        NumericValue a = this;

        Type precision = maxPrecision(a, b);
        switch (precision) {
            case INTEGER:
                return new SesameNumericValue(a.intValue() + b.intValue());
            case LONG:
                return new SesameNumericValue(a.longValue() + b.longValue());
            case FLOAT:
                return new SesameNumericValue(a.floatValue() + b.floatValue());
            case DOUBLE:
                return new SesameNumericValue(a.doubleValue() + b.doubleValue());
            case DECIMAL:
                return new SesameNumericValue(a.decimalValue().add(b.decimalValue()));
            default:
                // This shouldn't happen.
                return null;
        }
    }

    public NumericValue sub(final NumericValue b) {
        NumericValue a = this;

        Type precision = maxPrecision(a, b);
        switch (precision) {
            case INTEGER:
                return new SesameNumericValue(a.intValue() - b.intValue());
            case LONG:
                return new SesameNumericValue(a.longValue() - b.longValue());
            case FLOAT:
                return new SesameNumericValue(a.floatValue() - b.floatValue());
            case DOUBLE:
                return new SesameNumericValue(a.doubleValue() - b.doubleValue());
            case DECIMAL:
                return new SesameNumericValue(a.decimalValue().subtract(b.decimalValue()));
            default:
                // This shouldn't happen.
                return null;
        }
    }

    public NumericValue mul(final NumericValue b) {
        NumericValue a = this;

        Type precision = maxPrecision(a, b);
        switch (precision) {
            case INTEGER:
                return new SesameNumericValue(a.intValue() * b.intValue());
            case LONG:
                return new SesameNumericValue(a.longValue() * b.longValue());
            case FLOAT:
                return new SesameNumericValue(a.floatValue() * b.floatValue());
            case DOUBLE:
                return new SesameNumericValue(a.doubleValue() * b.doubleValue());
            case DECIMAL:
                return new SesameNumericValue(a.decimalValue().multiply(b.decimalValue()));
            default:
                // This shouldn't happen.
                return null;
        }
    }

    // Note: does not check for divide-by-zero.
    public NumericValue div(final NumericValue b) {
        NumericValue a = this;

        Type precision = maxPrecision(a, b);
        switch (precision) {
            case INTEGER:
                return new SesameNumericValue(a.intValue() / b.intValue());
            case LONG:
                return new SesameNumericValue(a.longValue() / b.longValue());
            case FLOAT:
                return new SesameNumericValue(a.floatValue() / b.floatValue());
            case DOUBLE:
                return new SesameNumericValue(a.doubleValue() / b.doubleValue());
            case DECIMAL:
                return new SesameNumericValue(a.decimalValue().divide(b.decimalValue()));
            default:
                // This shouldn't happen.
                return null;
        }
    }

    // Note: does not check for divide-by-zero.
    public NumericValue mod(final NumericValue b) {
        NumericValue a = this;

        Type precision = maxPrecision(a, b);
        switch (precision) {
            case INTEGER:
                return new SesameNumericValue(a.intValue() % b.intValue());
            case LONG:
                return new SesameNumericValue(a.longValue() % b.longValue());
            case FLOAT:
                return new SesameNumericValue(a.floatValue() % b.floatValue());
            case DOUBLE:
                return new SesameNumericValue(a.doubleValue() % b.doubleValue());
            case DECIMAL:
                return new SesameNumericValue(a.decimalValue().remainder(b.decimalValue()).abs());
            default:
                // This shouldn't happen.
                return null;
        }
    }

    public NumericValue pow(final NumericValue pow) {
        NumericValue a = this;

        if (Type.DECIMAL == a.getDatatype() && Type.INTEGER == pow.getDatatype()) {
            return new SesameNumericValue(a.decimalValue().pow(pow.intValue()));
        } else {
            double r = Math.pow(a.doubleValue(), pow.doubleValue());
            Type precision = maxPrecision(a, pow);
            switch (precision) {
                case INTEGER:
                    return new SesameNumericValue((int) r);
                case LONG:
                    return new SesameNumericValue((long) r);
                case FLOAT:
                    return new SesameNumericValue((float) r);
                case DOUBLE:
                    return new SesameNumericValue(r);
                case DECIMAL:
                    return new SesameNumericValue(r);
                default:
                    // This shouldn't happen.
                    return null;
            }
        }
    }
}
TOP

Related Classes of net.fortytwo.ripple.model.impl.sesame.SesameNumericValue

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.