use of org.apache.commons.jexl2.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;
}
use of org.apache.commons.jexl2.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;
}
use of org.apache.commons.jexl2.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);
}
}
use of org.apache.commons.jexl2.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 <=> 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;
}
use of org.apache.commons.jexl2.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;
}
Aggregations