Search in sources :

Example 6 with JexlArithmetic

use of org.apache.commons.jexl2.JexlArithmetic in project commons-jexl by apache.

the class Interpreter method processAnnotation.

/**
 * Processes an annotated statement.
 * @param stmt the statement
 * @param index the index of the current annotation being processed
 * @param data the contextual data
 * @return  the result of the statement block evaluation
 */
protected Object processAnnotation(final ASTAnnotatedStatement stmt, final int index, final Object data) {
    // are we evaluating the block ?
    final int last = stmt.jjtGetNumChildren() - 1;
    if (index == last) {
        final JexlNode cblock = stmt.jjtGetChild(last);
        // if the context has changed, might need a new interpreter
        final JexlArithmetic jexla = arithmetic.options(context);
        if (jexla == arithmetic) {
            return cblock.jjtAccept(Interpreter.this, data);
        }
        if (!arithmetic.getClass().equals(jexla.getClass()) && logger.isWarnEnabled()) {
            logger.warn("expected arithmetic to be " + arithmetic.getClass().getSimpleName() + ", got " + jexla.getClass().getSimpleName());
        }
        final Interpreter ii = new Interpreter(Interpreter.this, jexla);
        final Object r = cblock.jjtAccept(ii, data);
        if (ii.isCancelled()) {
            Interpreter.this.cancel();
        }
        return r;
    }
    // tracking whether we processed the annotation
    final AnnotatedCall jstmt = new AnnotatedCall(stmt, index + 1, data);
    // the annotation node and name
    final ASTAnnotation anode = (ASTAnnotation) stmt.jjtGetChild(index);
    final String aname = anode.getName();
    // evaluate the arguments
    final Object[] argv = anode.jjtGetNumChildren() > 0 ? visit((ASTArguments) anode.jjtGetChild(0), null) : null;
    // wrap the future, will recurse through annotation processor
    Object result;
    try {
        result = processAnnotation(aname, argv, jstmt);
        // not processing an annotation is an error
        if (!jstmt.isProcessed()) {
            return annotationError(anode, aname, null);
        }
    } catch (final JexlException xany) {
        throw xany;
    } catch (final Exception xany) {
        return annotationError(anode, aname, xany);
    }
    // the caller may return a return, break or continue
    if (result instanceof JexlException) {
        throw (JexlException) result;
    }
    return result;
}
Also used : JexlException(org.apache.commons.jexl3.JexlException) ASTAnnotation(org.apache.commons.jexl3.parser.ASTAnnotation) JexlNode(org.apache.commons.jexl3.parser.JexlNode) JexlArithmetic(org.apache.commons.jexl3.JexlArithmetic) ASTArguments(org.apache.commons.jexl3.parser.ASTArguments) JexlException(org.apache.commons.jexl3.JexlException)

Example 7 with JexlArithmetic

use of org.apache.commons.jexl2.JexlArithmetic in project commons-jexl by apache.

the class Uberspect method getArithmetic.

@Override
public JexlArithmetic.Uberspect getArithmetic(final JexlArithmetic arithmetic) {
    JexlArithmetic.Uberspect jau = null;
    if (arithmetic != null) {
        final Class<? extends JexlArithmetic> aclass = arithmetic.getClass();
        Set<JexlOperator> ops = operatorMap.get(aclass);
        if (ops == null) {
            ops = EnumSet.noneOf(JexlOperator.class);
            // deal only with derived classes
            if (!JexlArithmetic.class.equals(aclass)) {
                for (final JexlOperator op : JexlOperator.values()) {
                    final Method[] methods = getMethods(arithmetic.getClass(), op.getMethodName());
                    if (methods != null) {
                        mloop: for (final Method method : methods) {
                            final Class<?>[] parms = method.getParameterTypes();
                            if (parms.length != op.getArity()) {
                                continue;
                            }
                            // - nor overridden (not present in base class)
                            if (!JexlArithmetic.class.equals(method.getDeclaringClass())) {
                                try {
                                    JexlArithmetic.class.getMethod(method.getName(), method.getParameterTypes());
                                } catch (final NoSuchMethodException xmethod) {
                                    // method was not found in JexlArithmetic; this is an operator definition
                                    ops.add(op);
                                }
                            }
                        }
                    }
                }
            }
            // register this arithmetic class in the operator map
            operatorMap.put(aclass, ops);
        }
        jau = new ArithmeticUberspect(arithmetic, ops);
    }
    return jau;
}
Also used : JexlOperator(org.apache.commons.jexl3.JexlOperator) JexlArithmetic(org.apache.commons.jexl3.JexlArithmetic) JexlMethod(org.apache.commons.jexl3.introspection.JexlMethod) Method(java.lang.reflect.Method)

Example 8 with JexlArithmetic

use of org.apache.commons.jexl2.JexlArithmetic 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 9 with JexlArithmetic

use of org.apache.commons.jexl2.JexlArithmetic 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 10 with JexlArithmetic

use of org.apache.commons.jexl2.JexlArithmetic 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)

Aggregations

JexlArithmetic (org.apache.commons.jexl3.JexlArithmetic)11 JexlException (org.apache.commons.jexl3.JexlException)8 JexlMethod (org.apache.commons.jexl3.introspection.JexlMethod)8 JexlUberspect (org.apache.commons.jexl3.introspection.JexlUberspect)5 JexlOperator (org.apache.commons.jexl3.JexlOperator)2 JexlEvaluation (datawave.query.function.JexlEvaluation)1 EvaluationTrackingNestedIterator (datawave.query.iterator.profile.EvaluationTrackingNestedIterator)1 DefaultArithmetic (datawave.query.jexl.DefaultArithmetic)1 StatefulArithmetic (datawave.query.jexl.StatefulArithmetic)1 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 InterruptedIOException (java.io.InterruptedIOException)1 Method (java.lang.reflect.Method)1 BigDecimal (java.math.BigDecimal)1 MalformedURLException (java.net.MalformedURLException)1 Collection (java.util.Collection)1 Key (org.apache.accumulo.core.data.Key)1 Range (org.apache.accumulo.core.data.Range)1 IterationInterruptedException (org.apache.accumulo.core.iterators.IterationInterruptedException)1 TabletClosedException (org.apache.accumulo.tserver.tablet.TabletClosedException)1