use of org.apache.commons.jexl2.JexlException in project opennms by OpenNMS.
the class JEXLExpressionEngine method applyExpressions.
/**
* {@inheritDoc}
*/
@Override
public void applyExpressions(final QueryRequest request, final FetchResults results) throws ExpressionException {
Preconditions.checkNotNull(request, "request argument");
Preconditions.checkNotNull(results, "results argument");
final int numExpressions = request.getExpressions().size();
// Don't do anything if there are no expressions
if (numExpressions < 1) {
return;
}
// Use to keep track of transient expression so that we don't
// allocate memory to store their results
int numNonTransientExpression = 0;
boolean[] transientFlags = new boolean[numExpressions];
// Compile the expressions
int j, k = 0;
final LinkedHashMap<String, org.apache.commons.jexl2.Expression> expressions = Maps.newLinkedHashMap();
for (final Expression e : request.getExpressions()) {
// Populate the transientFlags array
transientFlags[k] = e.getTransient();
if (!transientFlags[k]) {
numNonTransientExpression++;
}
k++;
try {
expressions.put(e.getLabel(), jexl.createExpression(e.getExpression()));
} catch (JexlException ex) {
throw new ExpressionException(ex, "Failed to parse expression label '{}'.", e.getLabel());
}
}
// Prepare the JEXL context
final Map<String, Object> jexlValues = Maps.newHashMap();
final JexlContext context = new MapContext(jexlValues);
// Add constants (i.e. values from strings.properties) retrieved by the fetch operation
jexlValues.putAll(results.getConstants());
LOG.debug("JEXL context constants: {}", jexlValues);
// Add some additional constants for ease of use
jexlValues.put("__inf", Double.POSITIVE_INFINITY);
jexlValues.put("__neg_inf", Double.NEGATIVE_INFINITY);
jexlValues.put("NaN", Double.NaN);
jexlValues.put("__E", java.lang.Math.E);
jexlValues.put("__PI", java.lang.Math.PI);
// Add JexlEvaluateFunctions with current context and jexl engine to allow string constants to be evaluated.
JexlEvaluateFunctions jexlEvaluateFunctions = new JexlEvaluateFunctions(context, jexl);
jexl.getFunctions().put("jexl", jexlEvaluateFunctions);
final long[] timestamps = results.getTimestamps();
final Map<String, double[]> columns = results.getColumns();
final int numRows = timestamps.length;
// Calculate the time span
jexlValues.put("__diff_time", numRows < 1 ? 0d : timestamps[numRows - 1] - timestamps[0]);
final double[][] expressionValues = new double[numNonTransientExpression][numRows];
// Iterate through all of the rows, apply the expressions
for (int i = 0; i < numRows; i++) {
// Evaluate every expression, in the same order as which they appeared in the query
j = k = 0;
for (final Map.Entry<String, org.apache.commons.jexl2.Expression> expressionEntry : expressions.entrySet()) {
// Update the timestamp
jexlValues.put("timestamp", timestamps[i]);
// add index as a referenced variable in context
jexlValues.put("__i", Integer.valueOf(i));
// overwriting values from the last loop
for (final String sourceLabel : columns.keySet()) {
jexlValues.put(sourceLabel, columns.get(sourceLabel)[i]);
// add reference to complete array for each column to allow backwards referencing of samples
jexlValues.put("__" + sourceLabel, columns.get(sourceLabel));
}
// Evaluate the expression
try {
Object derived = expressionEntry.getValue().evaluate(context);
double derivedAsDouble = Utils.toDouble(derived);
// Only store the values for non-transient expressions
if (!transientFlags[j++]) {
expressionValues[k++][i] = derivedAsDouble;
}
// Store the result back in the context, so that it can be referenced
// by subsequent expression in the row
jexlValues.put(expressionEntry.getKey(), derivedAsDouble);
} catch (NullPointerException | NumberFormatException e) {
throw new ExpressionException(e, "The return value from expression with label '" + expressionEntry.getKey() + "' could not be cast to a Double.");
} catch (JexlException e) {
throw new ExpressionException(e, "Failed to evaluate expression with label '" + expressionEntry.getKey() + "'.");
}
}
}
// Store the results
j = k = 0;
for (final String expressionLabel : expressions.keySet()) {
if (!transientFlags[j++]) {
columns.put(expressionLabel, expressionValues[k++]);
}
}
}
use of org.apache.commons.jexl2.JexlException in project traccar by tananaev.
the class ComputedAttributesHandler method handlePosition.
@Override
protected Position handlePosition(Position position) {
Collection<Attribute> attributes = Context.getAttributesManager().getItems(Context.getAttributesManager().getAllDeviceItems(position.getDeviceId()));
for (Attribute attribute : attributes) {
if (attribute.getAttribute() != null) {
Object result = null;
try {
result = computeAttribute(attribute, position);
} catch (JexlException error) {
Log.warning(error);
}
if (result != null) {
try {
switch(attribute.getType()) {
case "number":
Number numberValue = (Number) result;
position.getAttributes().put(attribute.getAttribute(), numberValue);
break;
case "boolean":
Boolean booleanValue = (Boolean) result;
position.getAttributes().put(attribute.getAttribute(), booleanValue);
break;
default:
position.getAttributes().put(attribute.getAttribute(), result.toString());
}
} catch (ClassCastException error) {
Log.warning(error);
}
}
}
}
return position;
}
use of org.apache.commons.jexl2.JexlException in project traccar by traccar.
the class ComputedAttributesHandler method handlePosition.
@Override
protected Position handlePosition(Position position) {
Collection<Attribute> attributes = Context.getAttributesManager().getItems(Context.getAttributesManager().getAllDeviceItems(position.getDeviceId()));
for (Attribute attribute : attributes) {
if (attribute.getAttribute() != null) {
Object result = null;
try {
result = computeAttribute(attribute, position);
} catch (JexlException error) {
Log.warning(error);
}
if (result != null) {
try {
switch(attribute.getType()) {
case "number":
Number numberValue = (Number) result;
position.getAttributes().put(attribute.getAttribute(), numberValue);
break;
case "boolean":
Boolean booleanValue = (Boolean) result;
position.getAttributes().put(attribute.getAttribute(), booleanValue);
break;
default:
position.getAttributes().put(attribute.getAttribute(), result.toString());
}
} catch (ClassCastException error) {
Log.warning(error);
}
}
}
}
return position;
}
use of org.apache.commons.jexl2.JexlException in project javautils by jiadongpo.
the class PropsUtils method resolveVariableExpression.
/**
* Function that looks for expressions to parse. It parses backwards to capture embedded
* expressions
*/
private static String resolveVariableExpression(final String value, final int last, final JexlEngine jexl) {
final int lastIndex = value.lastIndexOf("$(", last);
if (lastIndex == -1) {
return value;
}
// Want to check that everything is well formed, and that
// we properly capture $( ...(...)...).
int bracketCount = 0;
int nextClosed = lastIndex + 2;
for (; nextClosed < value.length(); ++nextClosed) {
if (value.charAt(nextClosed) == '(') {
bracketCount++;
} else if (value.charAt(nextClosed) == ')') {
bracketCount--;
if (bracketCount == -1) {
break;
}
}
}
if (nextClosed == value.length()) {
throw new IllegalArgumentException("Expression " + value + " not well formed.");
}
final String innerExpression = value.substring(lastIndex + 2, nextClosed);
Object result = null;
try {
final Expression e = jexl.createExpression(innerExpression);
result = e.evaluate(new MapContext());
} catch (final JexlException e) {
throw new IllegalArgumentException("Expression " + value + " not well formed. " + e.getMessage(), e);
}
if (result == null) {
// for backward compatibility it is best to return value
return value;
}
final String newValue = value.substring(0, lastIndex) + result.toString() + value.substring(nextClosed + 1);
return resolveVariableExpression(newValue, lastIndex, jexl);
}
use of org.apache.commons.jexl2.JexlException in project jmxtrans by jmxtrans.
the class JexlNamingStrategy method formatName.
/**
* Format the name for the given result.
*
* @param result - the result of a JMX query.
* @return String - the formatted string resulting from the expression, or null if the formatting fails.
*/
@Override
public String formatName(Result result) {
String formatted;
JexlContext context = new MapContext();
this.populateContext(context, result);
try {
formatted = (String) this.parsedExpr.evaluate(context);
} catch (JexlException jexlExc) {
LOG.error("error applying JEXL expression to query results", jexlExc);
formatted = null;
}
return formatted;
}
Aggregations