use of org.codehaus.janino.ExpressionEvaluator in project flink by apache.
the class CompileUtils method compileExpression.
/**
* Compiles an expression code to a janino {@link ExpressionEvaluator}.
*
* @param code the expression code
* @param argumentNames the expression argument names
* @param argumentClasses the expression argument classes
* @param returnClass the return type of the expression
* @return the compiled class
*/
public static ExpressionEvaluator compileExpression(String code, List<String> argumentNames, List<Class<?>> argumentClasses, Class<?> returnClass) {
try {
ExpressionEntry key = new ExpressionEntry(code, argumentNames, argumentClasses, returnClass);
return COMPILED_EXPRESSION_CACHE.get(key, () -> {
ExpressionEvaluator expressionEvaluator = new ExpressionEvaluator();
// Input args
expressionEvaluator.setParameters(argumentNames.toArray(new String[0]), argumentClasses.toArray(new Class[0]));
// Result type
expressionEvaluator.setExpressionType(returnClass);
try {
// Compile
expressionEvaluator.cook(code);
} catch (CompileException e) {
throw new InvalidProgramException("Table program cannot be compiled. This is a bug. Please file an issue.\nExpression: " + code, e);
}
return expressionEvaluator;
});
} catch (Exception e) {
throw new FlinkRuntimeException(e.getMessage(), e);
}
}
use of org.codehaus.janino.ExpressionEvaluator in project pentaho-kettle by pentaho.
the class Janino method calcFields.
private Object[] calcFields(RowMetaInterface rowMeta, Object[] r) throws KettleValueException {
try {
Object[] outputRowData = RowDataUtil.createResizedCopy(r, data.outputRowMeta.size());
int tempIndex = rowMeta.size();
//
if (data.expressionEvaluators == null) {
data.expressionEvaluators = new ExpressionEvaluator[meta.getFormula().length];
data.argumentIndexes = new ArrayList<List<Integer>>();
for (int i = 0; i < meta.getFormula().length; i++) {
List<Integer> argIndexes = new ArrayList<Integer>();
data.argumentIndexes.add(argIndexes);
}
for (int m = 0; m < meta.getFormula().length; m++) {
List<Integer> argIndexes = data.argumentIndexes.get(m);
List<String> parameterNames = new ArrayList<String>();
List<Class<?>> parameterTypes = new ArrayList<Class<?>>();
for (int i = 0; i < data.outputRowMeta.size(); i++) {
ValueMetaInterface valueMeta = data.outputRowMeta.getValueMeta(i);
//
if (meta.getFormula()[m].getFormula().contains(valueMeta.getName())) {
// If so, add it to the indexes...
argIndexes.add(i);
parameterTypes.add(valueMeta.getNativeDataTypeClass());
parameterNames.add(valueMeta.getName());
}
}
JaninoMetaFunction fn = meta.getFormula()[m];
if (!Utils.isEmpty(fn.getFieldName())) {
// Create the expression evaluator: is relatively slow so we do it only for the first row...
//
data.expressionEvaluators[m] = new ExpressionEvaluator();
data.expressionEvaluators[m].setParameters(parameterNames.toArray(new String[parameterNames.size()]), parameterTypes.toArray(new Class<?>[parameterTypes.size()]));
data.expressionEvaluators[m].setReturnType(Object.class);
data.expressionEvaluators[m].setThrownExceptions(new Class<?>[] { Exception.class });
data.expressionEvaluators[m].cook(fn.getFormula());
} else {
throw new KettleException("Unable to find field name for formula [" + Const.NVL(fn.getFormula(), "") + "]");
}
}
}
for (int i = 0; i < meta.getFormula().length; i++) {
List<Integer> argumentIndexes = data.argumentIndexes.get(i);
// This method can only accept the specified number of values...
//
Object[] argumentData = new Object[argumentIndexes.size()];
for (int x = 0; x < argumentIndexes.size(); x++) {
int index = argumentIndexes.get(x);
ValueMetaInterface outputValueMeta = data.outputRowMeta.getValueMeta(index);
argumentData[x] = outputValueMeta.convertToNormalStorageType(outputRowData[index]);
}
Object formulaResult = data.expressionEvaluators[i].evaluate(argumentData);
Object value = null;
if (formulaResult == null) {
value = null;
} else {
ValueMetaInterface valueMeta = data.returnType[i];
if (valueMeta.getNativeDataTypeClass().isAssignableFrom(formulaResult.getClass())) {
value = formulaResult;
} else if (formulaResult instanceof Integer && valueMeta.getType() == ValueMetaInterface.TYPE_INTEGER) {
value = ((Integer) formulaResult).longValue();
} else {
throw new KettleValueException(BaseMessages.getString(PKG, "Janino.Error.ValueTypeMismatch", valueMeta.getTypeDesc(), meta.getFormula()[i].getFieldName(), formulaResult.getClass(), meta.getFormula()[i].getFormula()));
}
}
//
if (data.replaceIndex[i] < 0) {
outputRowData[tempIndex++] = value;
} else {
outputRowData[data.replaceIndex[i]] = value;
}
}
return outputRowData;
} catch (Exception e) {
throw new KettleValueException(e);
}
}
Aggregations