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

org.mvel2.ast.Sign Maven / Gradle / Ivy

package org.mvel2.ast;

import static org.mvel2.util.ParseTools.boxPrimitive;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;

import org.mvel2.CompileException;
import org.mvel2.MVEL;
import org.mvel2.ParserContext;
import org.mvel2.compiler.ExecutableStatement;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.util.ParseTools;

public class Sign extends ASTNode {

    private Signer signer;
    private ExecutableStatement stmt;

    public Sign(char[] expr, int start, int end, int fields, ParserContext pCtx) {
        super(pCtx);
        this.expr = expr;
        this.start = start + 1;
        this.offset = end - 1;
        this.fields = fields;

        if ((fields & COMPILE_IMMEDIATE) != 0) {
            stmt = (ExecutableStatement) ParseTools.subCompileExpression(expr, this.start, this.offset, pCtx);

            egressType = stmt.getKnownEgressType();

            if (egressType != null && egressType != Object.class) {
                initSigner(egressType);
            }
        }
    }

    public ExecutableStatement getStatement() {
        return stmt;
    }

    @Override
    public Object getReducedValueAccelerated(Object ctx, Object thisValue, VariableResolverFactory factory) {
        return sign(stmt.getValue(ctx, thisValue, factory));
    }

    @Override
    public Object getReducedValue(Object ctx, Object thisValue, VariableResolverFactory factory) {
        return sign(MVEL.eval(expr, start, offset, thisValue, factory));
    }

    private Object sign(Object o) {
        if (o == null) return null;
        if (signer == null) {
            if (egressType == null || egressType == Object.class) egressType = o.getClass();
            initSigner(egressType);
        }
        return signer.sign(o);
    }

    private void initSigner(Class type) {
        if (Integer.class.isAssignableFrom(type = boxPrimitive(type))) signer = new IntegerSigner();
        else if (Double.class.isAssignableFrom(type)) signer = new DoubleSigner();
        else if (Long.class.isAssignableFrom(type)) signer = new LongSigner();
        else if (Float.class.isAssignableFrom(type)) signer = new FloatSigner();
        else if (Short.class.isAssignableFrom(type)) signer = new ShortSigner();
        else if (BigInteger.class.isAssignableFrom(type)) signer = new BigIntSigner();
        else if (BigDecimal.class.isAssignableFrom(type)) signer = new BigDecSigner();
        else {
            throw new CompileException("illegal use of '-': cannot be applied to: " + type.getName(), expr, start);
        }

    }

    @Override
    public boolean isIdentifier() {
        return false;
    }

    private interface Signer extends Serializable {

        public Object sign(Object o);
    }

    private class IntegerSigner implements Signer {

        public Object sign(Object o) {
            return -((Integer) o);
        }
    }

    private class ShortSigner implements Signer {

        public Object sign(Object o) {
            return -((Short) o);
        }
    }

    private class LongSigner implements Signer {

        public Object sign(Object o) {
            return -((Long) o);
        }
    }

    private class DoubleSigner implements Signer {

        public Object sign(Object o) {
            return -((Double) o);
        }
    }

    private class FloatSigner implements Signer {

        public Object sign(Object o) {
            return -((Float) o);
        }
    }

    private class BigIntSigner implements Signer {

        public Object sign(Object o) {
            return new BigInteger(String.valueOf(-(((BigInteger) o).longValue())));
        }
    }

    private class BigDecSigner implements Signer {

        public Object sign(Object o) {
            return new BigDecimal(-((BigDecimal) o).doubleValue());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy