Search in sources :

Example 11 with JexlMethod

use of org.apache.commons.jexl3.introspection.JexlMethod in project commons-jexl by apache.

the class Interpreter method visit.

@Override
protected Object visit(final ASTUnaryPlusNode node, final Object data) {
    // use cached value if literal
    final Object value = node.jjtGetValue();
    if (value != null && !(value instanceof JexlMethod)) {
        return value;
    }
    final JexlNode valNode = node.jjtGetChild(0);
    final Object val = valNode.jjtAccept(this, data);
    try {
        final Object result = operators.tryOverload(node, JexlOperator.POSITIVIZE, val);
        if (result != JexlEngine.TRY_FAILED) {
            return result;
        }
        final Object number = arithmetic.positivize(val);
        if (valNode instanceof ASTNumberLiteral && number instanceof Number && arithmetic.isPositivizeStable()) {
            node.jjtSetValue(number);
        }
        return number;
    } catch (final ArithmeticException xrt) {
        throw new JexlException(valNode, "- error", xrt);
    }
}
Also used : JexlMethod(org.apache.commons.jexl3.introspection.JexlMethod) JexlException(org.apache.commons.jexl3.JexlException) JexlNode(org.apache.commons.jexl3.parser.JexlNode) ASTNumberLiteral(org.apache.commons.jexl3.parser.ASTNumberLiteral)

Example 12 with JexlMethod

use of org.apache.commons.jexl3.introspection.JexlMethod in project commons-jexl by apache.

the class Operators method empty.

/**
 * Check for emptyness of various types: Collection, Array, Map, String, and anything that has a boolean isEmpty()
 * method.
 * <p>Note that the result may not be a boolean.
 *
 * @param node   the node holding the object
 * @param object the object to check the emptyness of
 * @return the evaluation result
 */
protected Object empty(final JexlNode node, final Object object) {
    if (object == null) {
        return true;
    }
    Object result = tryOverload(node, JexlOperator.EMPTY, object);
    if (result != JexlEngine.TRY_FAILED) {
        return result;
    }
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    result = arithmetic.isEmpty(object, null);
    if (result == null) {
        final JexlUberspect uberspect = interpreter.uberspect;
        result = false;
        // check if there is an isEmpty method on the object that returns a
        // boolean and if so, just use it
        final JexlMethod vm = uberspect.getMethod(object, "isEmpty", Interpreter.EMPTY_PARAMS);
        if (returnsBoolean(vm)) {
            try {
                result = vm.invoke(object, Interpreter.EMPTY_PARAMS);
            } catch (final Exception xany) {
                interpreter.operatorError(node, JexlOperator.EMPTY, xany);
            }
        }
    }
    return !(result instanceof Boolean) || (Boolean) result;
}
Also used : JexlMethod(org.apache.commons.jexl3.introspection.JexlMethod) JexlUberspect(org.apache.commons.jexl3.introspection.JexlUberspect) JexlArithmetic(org.apache.commons.jexl3.JexlArithmetic) JexlException(org.apache.commons.jexl3.JexlException)

Example 13 with JexlMethod

use of org.apache.commons.jexl3.introspection.JexlMethod in project commons-jexl by apache.

the class Operators method endsWith.

/**
 * The 'endsWith' operator implementation.
 * @param node     the node
 * @param operator the calling operator, ^= or ^!
 * @param left     the left operand
 * @param right    the right operand
 * @return true if left ends with right, false otherwise
 */
protected boolean endsWith(final JexlNode node, final String operator, final Object left, final Object right) {
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    final JexlUberspect uberspect = interpreter.uberspect;
    try {
        // try operator overload
        final Object result = tryOverload(node, JexlOperator.ENDSWITH, left, right);
        if (result instanceof Boolean) {
            return (Boolean) result;
        }
        // use arithmetic / pattern matching ?
        final Boolean matched = arithmetic.endsWith(left, right);
        if (matched != null) {
            return matched;
        }
        // try a endsWith method (duck type)
        try {
            final Object[] argv = { right };
            JexlMethod vm = uberspect.getMethod(left, "endsWith", argv);
            if (returnsBoolean(vm)) {
                return (Boolean) vm.invoke(left, argv);
            }
            if (arithmetic.narrowArguments(argv)) {
                vm = uberspect.getMethod(left, "endsWith", argv);
                if (returnsBoolean(vm)) {
                    return (Boolean) vm.invoke(left, argv);
                }
            }
        } catch (final Exception e) {
            throw new JexlException(node, operator + " error", e);
        }
        // defaults to equal
        return arithmetic.equals(left, right);
    } catch (final ArithmeticException xrt) {
        throw new JexlException(node, operator + " error", xrt);
    }
}
Also used : JexlMethod(org.apache.commons.jexl3.introspection.JexlMethod) JexlException(org.apache.commons.jexl3.JexlException) JexlUberspect(org.apache.commons.jexl3.introspection.JexlUberspect) JexlArithmetic(org.apache.commons.jexl3.JexlArithmetic) JexlException(org.apache.commons.jexl3.JexlException)

Example 14 with JexlMethod

use of org.apache.commons.jexl3.introspection.JexlMethod in project commons-jexl by apache.

the class Operators method size.

/**
 * Calculate the <code>size</code> of various types:
 * Collection, Array, Map, String, and anything that has a int size() method.
 * <p>Note that the result may not be an integer.
 *
 * @param node   the node that gave the value to size
 * @param object the object to get the size of
 * @return the evaluation result
 */
protected Object size(final JexlNode node, final Object object) {
    if (object == null) {
        return 0;
    }
    Object result = tryOverload(node, JexlOperator.SIZE, object);
    if (result != JexlEngine.TRY_FAILED) {
        return result;
    }
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    result = arithmetic.size(object, null);
    if (result == null) {
        final JexlUberspect uberspect = interpreter.uberspect;
        // check if there is a size method on the object that returns an
        // integer and if so, just use it
        final JexlMethod vm = uberspect.getMethod(object, "size", Interpreter.EMPTY_PARAMS);
        if (returnsInteger(vm)) {
            try {
                result = vm.invoke(object, Interpreter.EMPTY_PARAMS);
            } catch (final Exception xany) {
                interpreter.operatorError(node, JexlOperator.SIZE, xany);
            }
        }
    }
    return result instanceof Number ? ((Number) result).intValue() : 0;
}
Also used : JexlMethod(org.apache.commons.jexl3.introspection.JexlMethod) JexlUberspect(org.apache.commons.jexl3.introspection.JexlUberspect) JexlArithmetic(org.apache.commons.jexl3.JexlArithmetic) JexlException(org.apache.commons.jexl3.JexlException)

Example 15 with JexlMethod

use of org.apache.commons.jexl3.introspection.JexlMethod in project commons-jexl by apache.

the class Operators method startsWith.

/**
 * The 'startsWith' operator implementation.
 * @param node     the node
 * @param operator the calling operator, $= or $!
 * @param left     the left operand
 * @param right    the right operand
 * @return true if left starts with right, false otherwise
 */
protected boolean startsWith(final JexlNode node, final String operator, final Object left, final Object right) {
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    final JexlUberspect uberspect = interpreter.uberspect;
    try {
        // try operator overload
        final Object result = tryOverload(node, JexlOperator.STARTSWITH, left, right);
        if (result instanceof Boolean) {
            return (Boolean) result;
        }
        // use arithmetic / pattern matching ?
        final Boolean matched = arithmetic.startsWith(left, right);
        if (matched != null) {
            return matched;
        }
        // try a startsWith method (duck type)
        try {
            final Object[] argv = { right };
            JexlMethod vm = uberspect.getMethod(left, "startsWith", argv);
            if (returnsBoolean(vm)) {
                return (Boolean) vm.invoke(left, argv);
            }
            if (arithmetic.narrowArguments(argv)) {
                vm = uberspect.getMethod(left, "startsWith", argv);
                if (returnsBoolean(vm)) {
                    return (Boolean) vm.invoke(left, argv);
                }
            }
        } catch (final Exception e) {
            throw new JexlException(node, operator + " error", e);
        }
        // defaults to equal
        return arithmetic.equals(left, right);
    } catch (final ArithmeticException xrt) {
        throw new JexlException(node, operator + " error", xrt);
    }
}
Also used : JexlMethod(org.apache.commons.jexl3.introspection.JexlMethod) JexlException(org.apache.commons.jexl3.JexlException) JexlUberspect(org.apache.commons.jexl3.introspection.JexlUberspect) JexlArithmetic(org.apache.commons.jexl3.JexlArithmetic) JexlException(org.apache.commons.jexl3.JexlException)

Aggregations

JexlMethod (org.apache.commons.jexl3.introspection.JexlMethod)18 JexlException (org.apache.commons.jexl3.JexlException)14 JexlArithmetic (org.apache.commons.jexl3.JexlArithmetic)7 JexlUberspect (org.apache.commons.jexl3.introspection.JexlUberspect)7 Test (org.junit.Test)4 JexlPropertyGet (org.apache.commons.jexl3.introspection.JexlPropertyGet)3 JexlInfo (org.apache.commons.jexl3.JexlInfo)2 ASTNumberLiteral (org.apache.commons.jexl3.parser.ASTNumberLiteral)2 JexlNode (org.apache.commons.jexl3.parser.JexlNode)2 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Optional (java.util.Optional)1 JexlOperator (org.apache.commons.jexl3.JexlOperator)1 JexlScript (org.apache.commons.jexl3.JexlScript)1 JexlPropertySet (org.apache.commons.jexl3.introspection.JexlPropertySet)1 ASTIdentifier (org.apache.commons.jexl3.parser.ASTIdentifier)1 ASTIdentifierAccess (org.apache.commons.jexl3.parser.ASTIdentifierAccess)1 ASTJexlScript (org.apache.commons.jexl3.parser.ASTJexlScript)1