Repository: incubator-nifi Updated Branches: refs/heads/develop bfe39c0b8 -> fed987e77
NIFI-206: Build appropriate AnyAttribute, AllAttributes, AnyMatchingAttribute, etc. evaluators in the buildExpressionEvaluator method rather than building at evaluation time. This way, embedded expressions are also wrapped appropriately. Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/fed987e7 Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/fed987e7 Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/fed987e7 Branch: refs/heads/develop Commit: fed987e778e0e2488888ffe2ac3a916b68255aac Parents: bfe39c0 Author: Mark Payne <[email protected]> Authored: Tue Dec 30 09:16:14 2014 -0500 Committer: Mark Payne <[email protected]> Committed: Tue Dec 30 09:16:14 2014 -0500 ---------------------------------------------------------------------- .../attribute/expression/language/Query.java | 60 +++++++++++--------- .../expression/language/TestQuery.java | 10 ++++ 2 files changed, 42 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/fed987e7/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java ---------------------------------------------------------------------- diff --git a/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java b/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java index f4c1c0d..93ab7ad 100644 --- a/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java +++ b/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java @@ -636,32 +636,7 @@ public class Query { throw new IllegalStateException("A Query cannot be evaluated more than once"); } - Evaluator<?> chosenEvaluator = evaluator; - final Evaluator<?> rootEvaluator = getRootSubjectEvaluator(evaluator); - if (rootEvaluator != null) { - if (rootEvaluator instanceof MultiAttributeEvaluator) { - if (evaluator.getResultType() != ResultType.BOOLEAN) { - throw new AttributeExpressionLanguageParsingException("Found Multi-Attribute function but return type is " + evaluator.getResultType() + ", not " + ResultType.BOOLEAN + ", for query: " + query); - } - - 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: - chosenEvaluator = new AllAttributesEvaluator((BooleanEvaluator) evaluator, multiAttrEval); - break; - } - } - } - - return chosenEvaluator.evaluate(attributes); + return evaluator.evaluate(attributes); } Tree getTree() { @@ -843,8 +818,10 @@ public class Query { if (tree.getChildCount() == 0) { throw new AttributeExpressionLanguageParsingException("EXPRESSION tree node has no children"); } + + final Evaluator<?> evaluator; if (tree.getChildCount() == 1) { - return buildEvaluator(tree.getChild(0)); + evaluator = buildEvaluator(tree.getChild(0)); } else { // we can chain together functions in the form of: // ${x:trim():substring(1,2):trim()} @@ -852,8 +829,35 @@ public class Query { // 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. - return buildFunctionExpressionEvaluator(tree, 0); + evaluator = buildFunctionExpressionEvaluator(tree, 0); + } + + Evaluator<?> chosenEvaluator = evaluator; + final Evaluator<?> rootEvaluator = getRootSubjectEvaluator(evaluator); + if (rootEvaluator != null) { + if (rootEvaluator instanceof MultiAttributeEvaluator) { + if (evaluator.getResultType() != ResultType.BOOLEAN) { + throw new AttributeExpressionLanguageParsingException("Found Multi-Attribute function but return type is " + evaluator.getResultType() + ", not " + ResultType.BOOLEAN + ", for query: " + tree.getText()); + } + + 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: + chosenEvaluator = new AllAttributesEvaluator((BooleanEvaluator) evaluator, multiAttrEval); + break; + } + } } + + return chosenEvaluator; } private static Evaluator<?> buildFunctionExpressionEvaluator(final Tree tree, final int offset) { http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/fed987e7/commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java ---------------------------------------------------------------------- diff --git a/commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java b/commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java index a2b7214..dd7a7fe 100644 --- a/commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java +++ b/commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java @@ -1047,6 +1047,16 @@ public class TestQuery { assertEquals(ResultType.NUMBER, Query.getResultType("${header.size:toNumber()}")); } + @Test + public void testAnyAttributeEmbedded() { + final Map<String, String> attributes = new HashMap<>(); + attributes.put("a1", "test1"); + attributes.put("b2", "2test"); + attributes.put("c3", "3test3"); + + final String query = "${a1:equals('test1'):and( ${anyAttribute('a1','b2','c3'):contains('2')})}"; + verifyEquals(query, attributes, true); + } private void verifyEquals(final String expression, final Map<String, String> attributes, final Object expectedResult) { Query.validateExpression(expression, false);
