use of org.apache.nifi.attribute.expression.language.evaluation.selection.MultiAttributeEvaluator in project nifi by apache.
the class ExpressionCompiler method verifyMappingEvaluatorReduced.
private void verifyMappingEvaluatorReduced(final Evaluator<?> evaluator) {
final Evaluator<?> rightMostEvaluator;
if (evaluator instanceof IteratingEvaluator) {
rightMostEvaluator = ((IteratingEvaluator<?>) evaluator).getLogicEvaluator();
} else {
rightMostEvaluator = evaluator;
}
Evaluator<?> eval = rightMostEvaluator.getSubjectEvaluator();
Evaluator<?> lastEval = rightMostEvaluator;
while (eval != null) {
if (eval instanceof ReduceEvaluator) {
throw new AttributeExpressionLanguageParsingException("Expression attempts to call function '" + lastEval.getToken() + "' on the result of '" + eval.getToken() + "'. This is not allowed. Instead, use \"${literal( ${<embedded expression>} ):" + lastEval.getToken() + "(...)}\"");
}
lastEval = eval;
eval = eval.getSubjectEvaluator();
}
// if the result type of the evaluator is BOOLEAN, then it will always
// be reduced when evaluator.
final ResultType resultType = evaluator.getResultType();
if (resultType == ResultType.BOOLEAN) {
return;
}
final Evaluator<?> rootEvaluator = getRootSubjectEvaluator(evaluator);
if (rootEvaluator != null && rootEvaluator instanceof MultiAttributeEvaluator) {
final MultiAttributeEvaluator multiAttrEval = (MultiAttributeEvaluator) rootEvaluator;
switch(multiAttrEval.getEvaluationType()) {
case ALL_ATTRIBUTES:
case ALL_MATCHING_ATTRIBUTES:
case ALL_DELINEATED_VALUES:
{
if (!(evaluator instanceof ReduceEvaluator)) {
throw new AttributeExpressionLanguageParsingException("Cannot evaluate expression because it attempts to reference multiple attributes but does not use a reducing function");
}
break;
}
default:
throw new AttributeExpressionLanguageParsingException("Cannot evaluate expression because it attempts to reference multiple attributes but does not use a reducing function");
}
}
}
use of org.apache.nifi.attribute.expression.language.evaluation.selection.MultiAttributeEvaluator in project nifi by apache.
the class StandardPreparedQuery method getVariableImpact.
@Override
public VariableImpact getVariableImpact() {
final VariableImpact existing = this.variableImpact;
if (existing != null) {
return existing;
}
final Set<String> variables = new HashSet<>();
for (final Expression expression : expressions) {
if (!(expression instanceof CompiledExpression)) {
continue;
}
final CompiledExpression compiled = (CompiledExpression) expression;
for (final Evaluator<?> evaluator : compiled.getAllEvaluators()) {
if (evaluator instanceof AttributeEvaluator) {
final AttributeEvaluator attributeEval = (AttributeEvaluator) evaluator;
final Evaluator<String> nameEval = attributeEval.getNameEvaluator();
if (nameEval instanceof StringLiteralEvaluator) {
final String referencedVar = nameEval.evaluate(Collections.emptyMap()).getValue();
variables.add(referencedVar);
}
} else if (evaluator instanceof AllAttributesEvaluator) {
final AllAttributesEvaluator allAttrsEval = (AllAttributesEvaluator) evaluator;
final MultiAttributeEvaluator iteratingEval = allAttrsEval.getVariableIteratingEvaluator();
if (iteratingEval instanceof MultiNamedAttributeEvaluator) {
variables.addAll(((MultiNamedAttributeEvaluator) iteratingEval).getAttributeNames());
} else if (iteratingEval instanceof MultiMatchAttributeEvaluator) {
return VariableImpact.ALWAYS_IMPACTED;
}
} else if (evaluator instanceof AnyAttributeEvaluator) {
final AnyAttributeEvaluator allAttrsEval = (AnyAttributeEvaluator) evaluator;
final MultiAttributeEvaluator iteratingEval = allAttrsEval.getVariableIteratingEvaluator();
if (iteratingEval instanceof MultiNamedAttributeEvaluator) {
variables.addAll(((MultiNamedAttributeEvaluator) iteratingEval).getAttributeNames());
} else if (iteratingEval instanceof MultiMatchAttributeEvaluator) {
return VariableImpact.ALWAYS_IMPACTED;
}
} else if (evaluator instanceof MappingEvaluator) {
final MappingEvaluator<?> allAttrsEval = (MappingEvaluator<?>) evaluator;
final MultiAttributeEvaluator iteratingEval = allAttrsEval.getVariableIteratingEvaluator();
if (iteratingEval instanceof MultiNamedAttributeEvaluator) {
variables.addAll(((MultiNamedAttributeEvaluator) iteratingEval).getAttributeNames());
}
}
}
}
final VariableImpact impact = new NamedVariableImpact(variables);
this.variableImpact = impact;
return impact;
}
use of org.apache.nifi.attribute.expression.language.evaluation.selection.MultiAttributeEvaluator in project nifi by apache.
the class ExpressionCompiler method buildExpressionEvaluator.
@SuppressWarnings({ "rawtypes", "unchecked" })
private Evaluator<?> buildExpressionEvaluator(final Tree tree) {
if (tree.getChildCount() == 0) {
throw new AttributeExpressionLanguageParsingException("EXPRESSION tree node has no children");
}
final Evaluator<?> evaluator;
if (tree.getChildCount() == 1) {
evaluator = buildEvaluator(tree.getChild(0));
} else {
// we can chain together functions in the form of:
// ${x:trim():substring(1,2):trim()}
// in this case, the subject of the right-most function is the function to its left; its
// subject is the function to its left (the first trim()), and its subject is the value of
// the 'x' attribute. We accomplish this logic by iterating over all of the children of the
// tree from the right-most child going left-ward.
evaluator = buildFunctionExpressionEvaluator(tree, 0);
}
Evaluator<?> chosenEvaluator = evaluator;
final Evaluator<?> rootEvaluator = getRootSubjectEvaluator(evaluator);
if (rootEvaluator != null) {
if (rootEvaluator instanceof MultiAttributeEvaluator) {
final MultiAttributeEvaluator multiAttrEval = (MultiAttributeEvaluator) rootEvaluator;
switch(multiAttrEval.getEvaluationType()) {
case ANY_ATTRIBUTE:
case ANY_MATCHING_ATTRIBUTE:
case ANY_DELINEATED_VALUE:
chosenEvaluator = new AnyAttributeEvaluator((BooleanEvaluator) evaluator, multiAttrEval);
break;
case ALL_ATTRIBUTES:
case ALL_MATCHING_ATTRIBUTES:
case ALL_DELINEATED_VALUES:
{
final ResultType resultType = evaluator.getResultType();
if (resultType == ResultType.BOOLEAN) {
chosenEvaluator = new AllAttributesEvaluator((BooleanEvaluator) evaluator, multiAttrEval);
} else if (evaluator instanceof ReduceEvaluator) {
chosenEvaluator = new MappingEvaluator((ReduceEvaluator) evaluator, multiAttrEval);
} else {
throw new AttributeExpressionLanguageException("Cannot evaluate Expression because it attempts to reference multiple attributes but does not use a reducing function");
}
break;
}
}
evaluators.add(chosenEvaluator);
switch(multiAttrEval.getEvaluationType()) {
case ANY_ATTRIBUTE:
chosenEvaluator.setToken("anyAttribute");
break;
case ANY_MATCHING_ATTRIBUTE:
chosenEvaluator.setToken("anyMatchingAttribute");
break;
case ANY_DELINEATED_VALUE:
chosenEvaluator.setToken("anyDelineatedValue");
break;
case ALL_ATTRIBUTES:
chosenEvaluator.setToken("allAttributes");
break;
case ALL_MATCHING_ATTRIBUTES:
chosenEvaluator.setToken("allMatchingAttributes");
break;
case ALL_DELINEATED_VALUES:
chosenEvaluator.setToken("allDelineatedValues");
break;
}
}
}
return chosenEvaluator;
}
Aggregations