All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.kuseman.payloadbuilder.api.execution.Decimal Maven / Gradle / Ivy

The newest version!
package se.kuseman.payloadbuilder.api.execution;

import static java.util.Objects.requireNonNull;

import java.math.BigDecimal;
import java.math.RoundingMode;

import se.kuseman.payloadbuilder.api.catalog.Column;
import se.kuseman.payloadbuilder.api.catalog.Column.Type;
import se.kuseman.payloadbuilder.api.catalog.ResolvedType;
import se.kuseman.payloadbuilder.api.expression.IArithmeticBinaryExpression;

/** Wrapper class for data type {@link Column.Type#Decimal}. */
public class Decimal extends Number implements Comparable, ValueVector
{
    /** NOTE! PLB doesn't have support for specifying scaling of decimals (unless created with String/BigDecinal), scale is set to this in factory methods */
    private static final int SCALE = 6;

    private final BigDecimal value;

    private Decimal(BigDecimal value)
    {
        this.value = requireNonNull(value, "value");
    }

    // ValueVector

    @Override
    public int size()
    {
        return 1;
    }

    @Override
    public ResolvedType type()
    {
        return ResolvedType.of(Type.Decimal);
    }

    @Override
    public boolean isNull(int row)
    {
        return false;
    }

    @Override
    public Decimal getDecimal(int row)
    {
        return this;
    }

    // End ValueVector

    /** Process provided deicmal to this instance with provided arithmetic type. Returns a new {@link Decimal} */
    public Decimal processArithmetic(Decimal other, IArithmeticBinaryExpression.Type type)
    {
        switch (type)
        {
            case ADD:
                return new Decimal(value.add(other.value));
            case DIVIDE:
                return new Decimal(value.divide(other.value, RoundingMode.HALF_UP));
            case MODULUS:
                return new Decimal(value.remainder(other.value));
            case MULTIPLY:
                return new Decimal(value.multiply(other.value));
            case SUBTRACT:
                return new Decimal(value.subtract(other.value));
            default:
                throw new IllegalArgumentException("Unsupported arithmetic operation " + type);
        }
    }

    /** Negate this decimal returning a new instance */
    public Decimal negate()
    {
        return new Decimal(value.negate());
    }

    /** Convert this value as a {@link BigDecimal} */
    public BigDecimal asBigDecimal()
    {
        return value;
    }

    /** Return the absolute value of this decimal */
    public Decimal abs()
    {
        return Decimal.from(value.abs());
    }

    /** Return ceiling value of this decimal */
    public Decimal ceiling()
    {
        return Decimal.from(value.setScale(0, RoundingMode.CEILING));
    }

    /** Return floor value of this decimal */
    public Decimal floor()
    {
        return Decimal.from(value.setScale(0, RoundingMode.FLOOR));
    }

    @Override
    public int intValue()
    {
        return value.intValue();
    }

    @Override
    public long longValue()
    {
        return value.longValue();
    }

    @Override
    public float floatValue()
    {
        return value.floatValue();
    }

    @Override
    public double doubleValue()
    {
        return value.doubleValue();
    }

    @Override
    public int compareTo(Decimal o)
    {
        return value.compareTo(o.value);
    }

    @Override
    public int hashCode()
    {
        return value.hashCode();
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj == null)
        {
            return false;
        }
        else if (obj == this)
        {
            return true;
        }
        else if (obj instanceof Decimal)
        {
            Decimal that = (Decimal) obj;
            return value.equals(that.value);
        }
        return false;
    }

    @Override
    public String toString()
    {
        return value.toString();
    }

    /** Construct a deciaml from provided object. Tries to convert known types like BigDecimal/Strings etc. */
    public static Decimal from(Object value)
    {
        if (value instanceof Decimal)
        {
            return (Decimal) value;
        }
        else if (value instanceof BigDecimal)
        {
            return new Decimal((BigDecimal) value);
        }
        else if (value instanceof String
                || value instanceof UTF8String)
        {
            String str = value instanceof String ? (String) value
                    : ((UTF8String) value).toString();
            try
            {
                return new Decimal(new BigDecimal(str));
            }
            catch (NumberFormatException e)
            {
                throw new IllegalArgumentException("Cannot cast '" + str + "' to " + Type.Decimal);
            }
        }
        else if (value instanceof Number)
        {
            // Use highest number precision value
            return new Decimal(new BigDecimal(((Number) value).doubleValue()).setScale(SCALE, RoundingMode.HALF_UP));
        }

        throw new IllegalArgumentException("Cannot cast '" + value + "' to " + Type.Decimal);
    }

    /** Construct a deciaml from provided int */
    public static Decimal from(int value)
    {
        return new Decimal(new BigDecimal(value).setScale(SCALE, RoundingMode.HALF_UP));
    }

    /** Construct a deciaml from provided long */
    public static Decimal from(long value)
    {
        return new Decimal(new BigDecimal(value).setScale(SCALE, RoundingMode.HALF_UP));
    }

    /** Construct a deciaml from provided float */
    public static Decimal from(float value)
    {
        return new Decimal(new BigDecimal(value).setScale(SCALE, RoundingMode.HALF_UP));
    }

    /** Construct a deciaml from provided double */
    public static Decimal from(double value)
    {
        return new Decimal(new BigDecimal(value).setScale(SCALE, RoundingMode.HALF_UP));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy