Search in sources :

Example 1 with JexlArithmetic

use of org.apache.commons.jexl3.JexlArithmetic in project datawave by NationalSecurityAgency.

the class QueryIterator method buildDocumentIterator.

/**
 * Build the document iterator
 *
 * @param documentRange
 * @param seekRange
 * @param columnFamilies
 * @param inclusive
 * @return
 * @throws IOException
 */
protected NestedIterator<Key> buildDocumentIterator(Range documentRange, Range seekRange, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException, ConfigException, InstantiationException, IllegalAccessException {
    NestedIterator<Key> docIter = null;
    if (log.isTraceEnabled()) {
        log.trace("Batched queries is " + batchedQueries);
    }
    if (batchedQueries >= 1) {
        List<NestedQuery<Key>> nests = Lists.newArrayList();
        for (Entry<Range, String> queries : batchStack) {
            Range myRange = queries.getKey();
            if (log.isTraceEnabled()) {
                log.trace("Adding " + myRange + " from seekrange " + seekRange);
            }
            /*
                 * Only perform the following checks if start key is not infinite and document range is specified
                 */
            if (null != seekRange && !seekRange.isInfiniteStartKey()) {
                Key seekStartKey = seekRange.getStartKey();
                Key myStartKey = myRange.getStartKey();
                /*
                     * if our seek key is greater than our start key we can skip this batched query. myStartKey.compareTo(seekStartKey) must be <= 0, which
                     * means that startKey must be greater than or equal be seekStartKey
                     */
                if (null != myStartKey && null != seekStartKey && !seekRange.contains(myStartKey)) {
                    if (log.isTraceEnabled()) {
                        log.trace("skipping " + myRange);
                    }
                    continue;
                }
            }
            JexlArithmetic myArithmetic;
            if (arithmetic instanceof StatefulArithmetic) {
                myArithmetic = ((StatefulArithmetic) arithmetic).clone();
            } else {
                myArithmetic = new DefaultArithmetic();
            }
            // Parse the query
            ASTJexlScript myScript = null;
            JexlEvaluation eval = null;
            try {
                myScript = JexlASTHelper.parseJexlQuery(queries.getValue());
                eval = new JexlEvaluation(queries.getValue(), myArithmetic);
            } catch (Exception e) {
                throw new IOException("Could not parse the JEXL query: '" + this.getQuery() + "'", e);
            }
            // If we had an event-specific range previously, we need to
            // reset it back
            // to the source we created during init
            NestedIterator<Key> subDocIter = getOrSetKeySource(myRange, myScript);
            if (log.isTraceEnabled()) {
                log.trace("Using init()'ialized source: " + subDocIter.getClass().getName());
            }
            if (gatherTimingDetails()) {
                subDocIter = new EvaluationTrackingNestedIterator(QuerySpan.Stage.FieldIndexTree, trackingSpan, subDocIter, myEnvironment);
            }
            // Seek() the boolean logic stuff
            ((SeekableIterator) subDocIter).seek(myRange, columnFamilies, inclusive);
            NestedQuery<Key> nestedQueryObj = new NestedQuery<>();
            nestedQueryObj.setQuery(queries.getValue());
            nestedQueryObj.setIterator(subDocIter);
            nestedQueryObj.setQueryScript(myScript);
            nestedQueryObj.setEvaluation(eval);
            nestedQueryObj.setRange(queries.getKey());
            nests.add(nestedQueryObj);
        }
        docIter = new NestedQueryIterator<>(nests);
        // now lets start off the nested iterator
        docIter.initialize();
        initKeySource = docIter;
    } else {
        // If we had an event-specific range previously, we need to reset it back
        // to the source we created during init
        docIter = getOrSetKeySource(documentRange, script);
        initKeySource = docIter;
        if (log.isTraceEnabled()) {
            log.trace("Using init()'ialized source: " + this.initKeySource.getClass().getName());
        }
        if (gatherTimingDetails()) {
            docIter = new EvaluationTrackingNestedIterator(QuerySpan.Stage.FieldIndexTree, trackingSpan, docIter, myEnvironment);
        }
        // Seek() the boolean logic stuff
        ((SeekableIterator) docIter).seek(range, columnFamilies, inclusive);
        // now lets start off the nested iterator
        docIter.initialize();
    }
    return docIter;
}
Also used : DefaultArithmetic(datawave.query.jexl.DefaultArithmetic) ASTJexlScript(org.apache.commons.jexl2.parser.ASTJexlScript) JexlEvaluation(datawave.query.function.JexlEvaluation) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) Range(org.apache.accumulo.core.data.Range) ConfigException(org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException) IterationInterruptedException(org.apache.accumulo.core.iterators.IterationInterruptedException) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) TabletClosedException(org.apache.accumulo.tserver.tablet.TabletClosedException) MalformedURLException(java.net.MalformedURLException) JexlArithmetic(org.apache.commons.jexl2.JexlArithmetic) StatefulArithmetic(datawave.query.jexl.StatefulArithmetic) EvaluationTrackingNestedIterator(datawave.query.iterator.profile.EvaluationTrackingNestedIterator) Key(org.apache.accumulo.core.data.Key)

Example 2 with JexlArithmetic

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

the class Operators method tryOverload.

/**
 * Attempts to call an operator.
 * <p>
 * This takes care of finding and caching the operator method when appropriate
 * @param node     the syntactic node
 * @param operator the operator
 * @param args     the arguments
 * @return the result of the operator evaluation or TRY_FAILED
 */
protected Object tryOverload(final JexlNode node, final JexlOperator operator, final Object... args) {
    if (operators != null && operators.overloads(operator)) {
        final JexlArithmetic arithmetic = interpreter.arithmetic;
        final boolean cache = interpreter.cache;
        try {
            if (cache) {
                final Object cached = node.jjtGetValue();
                if (cached instanceof JexlMethod) {
                    final JexlMethod me = (JexlMethod) cached;
                    final Object eval = me.tryInvoke(operator.getMethodName(), arithmetic, args);
                    if (!me.tryFailed(eval)) {
                        return eval;
                    }
                }
            }
            final JexlMethod vm = operators.getOperator(operator, args);
            if (vm != null && !isArithmetic(vm)) {
                final Object result = vm.invoke(arithmetic, args);
                if (cache) {
                    node.jjtSetValue(vm);
                }
                return result;
            }
        } catch (final Exception xany) {
            return interpreter.operatorError(node, operator, xany);
        }
    }
    return JexlEngine.TRY_FAILED;
}
Also used : JexlMethod(org.apache.commons.jexl3.introspection.JexlMethod) JexlArithmetic(org.apache.commons.jexl3.JexlArithmetic) JexlException(org.apache.commons.jexl3.JexlException)

Example 3 with JexlArithmetic

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

the class Operators method contains.

/**
 * The 'match'/'in' operator implementation.
 * <p>
 * Note that 'x in y' or 'x matches y' means 'y contains x' ;
 * the JEXL operator arguments order syntax is the reverse of this method call.
 * </p>
 * @param node  the node
 * @param op    the calling operator, =~ or !~
 * @param right the left operand
 * @param left  the right operand
 * @return true if left matches right, false otherwise
 */
protected boolean contains(final JexlNode node, final String op, 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.CONTAINS, left, right);
        if (result instanceof Boolean) {
            return (Boolean) result;
        }
        // use arithmetic / pattern matching ?
        final Boolean matched = arithmetic.contains(left, right);
        if (matched != null) {
            return matched;
        }
        // try a contains method (duck type set)
        try {
            final Object[] argv = { right };
            JexlMethod vm = uberspect.getMethod(left, "contains", argv);
            if (returnsBoolean(vm)) {
                return (Boolean) vm.invoke(left, argv);
            }
            if (arithmetic.narrowArguments(argv)) {
                vm = uberspect.getMethod(left, "contains", argv);
                if (returnsBoolean(vm)) {
                    return (Boolean) vm.invoke(left, argv);
                }
            }
        } catch (final Exception e) {
            throw new JexlException(node, op + " error", e);
        }
        // defaults to equal
        return arithmetic.equals(left, right);
    } catch (final ArithmeticException xrt) {
        throw new JexlException(node, op + " 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 4 with JexlArithmetic

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

the class Operators method tryAssignOverload.

/**
 * Evaluates an assign operator.
 * <p>
 * This takes care of finding and caching the operator method when appropriate.
 * If an overloads returns Operator.ASSIGN, it means the side-effect is complete.
 * Otherwise, a += b &lt;=&gt; a = a + b
 * </p>
 * @param node     the syntactic node
 * @param operator the operator
 * @param args     the arguments, the first one being the target of assignment
 * @return JexlOperator.ASSIGN if operation assignment has been performed,
 *         JexlEngine.TRY_FAILED if no operation was performed,
 *         the value to use as the side effect argument otherwise
 */
protected Object tryAssignOverload(final JexlNode node, final JexlOperator operator, final Object... args) {
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    if (args.length != operator.getArity()) {
        return JexlEngine.TRY_FAILED;
    }
    // try to call overload with side effect
    Object result = tryOverload(node, operator, args);
    if (result != JexlEngine.TRY_FAILED) {
        return result;
    }
    // call base operator
    final JexlOperator base = operator.getBaseOperator();
    if (base == null) {
        throw new IllegalArgumentException("must be called with a side-effect operator");
    }
    if (operators != null && operators.overloads(base)) {
        // in case there is an overload on the base operator
        try {
            final JexlMethod vm = operators.getOperator(base, args);
            if (vm != null) {
                result = vm.invoke(arithmetic, args);
                if (result != JexlEngine.TRY_FAILED) {
                    return result;
                }
            }
        } catch (final Exception xany) {
            interpreter.operatorError(node, base, xany);
        }
    }
    // base eval
    try {
        switch(operator) {
            case SELF_ADD:
                return arithmetic.add(args[0], args[1]);
            case SELF_SUBTRACT:
                return arithmetic.subtract(args[0], args[1]);
            case SELF_MULTIPLY:
                return arithmetic.multiply(args[0], args[1]);
            case SELF_DIVIDE:
                return arithmetic.divide(args[0], args[1]);
            case SELF_MOD:
                return arithmetic.mod(args[0], args[1]);
            case SELF_AND:
                return arithmetic.and(args[0], args[1]);
            case SELF_OR:
                return arithmetic.or(args[0], args[1]);
            case SELF_XOR:
                return arithmetic.xor(args[0], args[1]);
            default:
                // unexpected, new operator added?
                throw new UnsupportedOperationException(operator.getOperatorSymbol());
        }
    } catch (final Exception xany) {
        interpreter.operatorError(node, base, xany);
    }
    return JexlEngine.TRY_FAILED;
}
Also used : JexlMethod(org.apache.commons.jexl3.introspection.JexlMethod) JexlOperator(org.apache.commons.jexl3.JexlOperator) JexlArithmetic(org.apache.commons.jexl3.JexlArithmetic) JexlException(org.apache.commons.jexl3.JexlException)

Example 5 with JexlArithmetic

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

the class Engine method evalOptions.

/**
 * Obsolete version of options evaluation.
 * @param opts the obsolete instance of options
 * @return the newer class of options
 */
private JexlOptions evalOptions(final JexlEngine.Options opts) {
    // This condition and block for compatibility between 3.1 and 3.2
    final JexlOptions jexlo = options.copy();
    final JexlEngine jexl = this;
    jexlo.setCancellable(option(opts.isCancellable(), jexl.isCancellable()));
    jexlo.setSilent(option(opts.isSilent(), jexl.isSilent()));
    jexlo.setStrict(option(opts.isStrict(), jexl.isStrict()));
    final JexlArithmetic jexla = jexl.getArithmetic();
    jexlo.setStrictArithmetic(option(opts.isStrictArithmetic(), jexla.isStrict()));
    jexlo.setMathContext(opts.getArithmeticMathContext());
    jexlo.setMathScale(opts.getArithmeticMathScale());
    return jexlo;
}
Also used : JexlEngine(org.apache.commons.jexl3.JexlEngine) JexlOptions(org.apache.commons.jexl3.JexlOptions) JexlArithmetic(org.apache.commons.jexl3.JexlArithmetic)

Aggregations

JexlArithmetic (org.apache.commons.jexl3.JexlArithmetic)11 JexlMethod (org.apache.commons.jexl3.introspection.JexlMethod)9 JexlException (org.apache.commons.jexl3.JexlException)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 HashMap (java.util.HashMap)1 Map (java.util.Map)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