mirror of https://github.com/apache/nifi.git
NIFI-3206: Add ifElse function to Expression Language
This closes #1333 Signed-off-by: jpercivall <JPercivall@apache.org>
This commit is contained in:
parent
34627f78b7
commit
21ed556691
|
@ -182,6 +182,7 @@ SUBSTRING : 'substring';
|
||||||
REPLACE : 'replace';
|
REPLACE : 'replace';
|
||||||
REPLACE_FIRST : 'replaceFirst';
|
REPLACE_FIRST : 'replaceFirst';
|
||||||
REPLACE_ALL : 'replaceAll';
|
REPLACE_ALL : 'replaceAll';
|
||||||
|
IF_ELSE : 'ifElse';
|
||||||
|
|
||||||
// 4 arg functions
|
// 4 arg functions
|
||||||
GET_DELIMITED_FIELD : 'getDelimitedField';
|
GET_DELIMITED_FIELD : 'getDelimitedField';
|
||||||
|
|
|
@ -77,7 +77,7 @@ zeroArgString : (TO_UPPER | TO_LOWER | TRIM | TO_STRING | URL_ENCODE | URL_DECOD
|
||||||
oneArgString : ((SUBSTRING_BEFORE | SUBSTRING_BEFORE_LAST | SUBSTRING_AFTER | SUBSTRING_AFTER_LAST | REPLACE_NULL | REPLACE_EMPTY |
|
oneArgString : ((SUBSTRING_BEFORE | SUBSTRING_BEFORE_LAST | SUBSTRING_AFTER | SUBSTRING_AFTER_LAST | REPLACE_NULL | REPLACE_EMPTY |
|
||||||
PREPEND | APPEND | FORMAT | STARTS_WITH | ENDS_WITH | CONTAINS | JOIN | JSON_PATH | FROM_RADIX) LPAREN! anyArg RPAREN!) |
|
PREPEND | APPEND | FORMAT | STARTS_WITH | ENDS_WITH | CONTAINS | JOIN | JSON_PATH | FROM_RADIX) LPAREN! anyArg RPAREN!) |
|
||||||
(TO_RADIX LPAREN! anyArg (COMMA! anyArg)? RPAREN!);
|
(TO_RADIX LPAREN! anyArg (COMMA! anyArg)? RPAREN!);
|
||||||
twoArgString : ((REPLACE | REPLACE_FIRST | REPLACE_ALL) LPAREN! anyArg COMMA! anyArg RPAREN!) |
|
twoArgString : ((REPLACE | REPLACE_FIRST | REPLACE_ALL | IF_ELSE) LPAREN! anyArg COMMA! anyArg RPAREN!) |
|
||||||
(SUBSTRING LPAREN! anyArg (COMMA! anyArg)? RPAREN!);
|
(SUBSTRING LPAREN! anyArg (COMMA! anyArg)? RPAREN!);
|
||||||
fiveArgString : GET_DELIMITED_FIELD LPAREN! anyArg (COMMA! anyArg (COMMA! anyArg (COMMA! anyArg (COMMA! anyArg)?)?)?)? RPAREN!;
|
fiveArgString : GET_DELIMITED_FIELD LPAREN! anyArg (COMMA! anyArg (COMMA! anyArg (COMMA! anyArg (COMMA! anyArg)?)?)?)? RPAREN!;
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ import org.apache.nifi.attribute.expression.language.evaluation.functions.Greate
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.functions.GreaterThanOrEqualEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.GreaterThanOrEqualEvaluator;
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.functions.HostnameEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.HostnameEvaluator;
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.functions.IPEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.IPEvaluator;
|
||||||
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.IfElseEvaluator;
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.functions.InEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.InEvaluator;
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.functions.IndexOfEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.IndexOfEvaluator;
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.functions.IsEmptyEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.IsEmptyEvaluator;
|
||||||
|
@ -126,6 +127,7 @@ import org.antlr.runtime.CommonTokenStream;
|
||||||
import org.antlr.runtime.tree.Tree;
|
import org.antlr.runtime.tree.Tree;
|
||||||
|
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.FROM_RADIX;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.FROM_RADIX;
|
||||||
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.IF_ELSE;
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MATH;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MATH;
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ALL_ATTRIBUTES;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ALL_ATTRIBUTES;
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ALL_DELINEATED_VALUES;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ALL_DELINEATED_VALUES;
|
||||||
|
@ -1361,6 +1363,12 @@ public class Query {
|
||||||
return addToken(new JsonPathEvaluator(toStringEvaluator(subjectEvaluator),
|
return addToken(new JsonPathEvaluator(toStringEvaluator(subjectEvaluator),
|
||||||
toStringEvaluator(argEvaluators.get(0), "first argument to jsonPath")), "jsonPath");
|
toStringEvaluator(argEvaluators.get(0), "first argument to jsonPath")), "jsonPath");
|
||||||
}
|
}
|
||||||
|
case IF_ELSE: {
|
||||||
|
verifyArgCount(argEvaluators, 2, "ifElse");
|
||||||
|
return addToken(new IfElseEvaluator(toBooleanEvaluator(subjectEvaluator),
|
||||||
|
toStringEvaluator(argEvaluators.get(0), "argument to return if true"),
|
||||||
|
toStringEvaluator(argEvaluators.get(1), "argument to return if false")), "ifElse");
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw new AttributeExpressionLanguageParsingException("Expected a Function-type expression but got " + tree.toString());
|
throw new AttributeExpressionLanguageParsingException("Expected a Function-type expression but got " + tree.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.nifi.attribute.expression.language.evaluation.functions;
|
||||||
|
|
||||||
|
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
|
||||||
|
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
|
||||||
|
import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator;
|
||||||
|
import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResult;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class IfElseEvaluator extends StringEvaluator {
|
||||||
|
|
||||||
|
private final Evaluator<Boolean> subject;
|
||||||
|
private final Evaluator<String> trueEvaluator;
|
||||||
|
private final Evaluator<String> falseEvaluator;
|
||||||
|
|
||||||
|
public IfElseEvaluator(final Evaluator<Boolean> subject, final Evaluator<String> trueEvaluator, final Evaluator<String> falseEvaluator) {
|
||||||
|
this.subject = subject;
|
||||||
|
this.trueEvaluator = trueEvaluator;
|
||||||
|
this.falseEvaluator = falseEvaluator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QueryResult<String> evaluate(final Map<String, String> attributes) {
|
||||||
|
final QueryResult<Boolean> subjectValue = subject.evaluate(attributes);
|
||||||
|
if (subjectValue == null) {
|
||||||
|
return new StringQueryResult(null);
|
||||||
|
}
|
||||||
|
final String ifElseValue = (Boolean.TRUE.equals(subjectValue.getValue())) ? trueEvaluator.evaluate(attributes).getValue() : falseEvaluator.evaluate(attributes).getValue();
|
||||||
|
return new StringQueryResult(ifElseValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Evaluator<?> getSubjectEvaluator() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1684,6 +1684,23 @@ public class TestQuery {
|
||||||
verifyEquals("${string:unescapeHtml4()}", attributes, "special ♣");
|
verifyEquals("${string:unescapeHtml4()}", attributes, "special ♣");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIfElse() {
|
||||||
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
|
verifyEquals("${attr:isNull():ifElse('a', 'b')}", attributes, "a");
|
||||||
|
verifyEquals("${attr:ifElse('a', 'b')}", attributes, "b");
|
||||||
|
attributes.put("attr", "hello");
|
||||||
|
verifyEquals("${attr:isNull():ifElse('a', 'b')}", attributes, "b");
|
||||||
|
verifyEquals("${attr:ifElse('a', 'b')}", attributes, "b");
|
||||||
|
attributes.put("attr", "true");
|
||||||
|
verifyEquals("${attr:ifElse('a', 'b')}", attributes, "a");
|
||||||
|
|
||||||
|
verifyEquals("${attr2:isNull():ifElse('a', 'b')}", attributes, "a");
|
||||||
|
verifyEquals("${literal(true):ifElse('a', 'b')}", attributes, "a");
|
||||||
|
verifyEquals("${literal(true):ifElse(false, 'b')}", attributes, "false");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyEquals(final String expression, final Map<String, String> attributes, final Object expectedResult) {
|
private void verifyEquals(final String expression, final Map<String, String> attributes, final Object expectedResult) {
|
||||||
verifyEquals(expression,attributes, null, expectedResult);
|
verifyEquals(expression,attributes, null, expectedResult);
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,7 @@ interpreted as literals. For example these two expressions are valid (without th
|
||||||
One of the most powerful features of the Expression Language is the ability to compare an attribute value against
|
One of the most powerful features of the Expression Language is the ability to compare an attribute value against
|
||||||
some other value. This is used often, for example, to configure how a Processor should route data. The following
|
some other value. This is used often, for example, to configure how a Processor should route data. The following
|
||||||
functions are used for performing boolean logic, such as comparing two values.
|
functions are used for performing boolean logic, such as comparing two values.
|
||||||
Each of these functions returns a value of type Boolean.
|
Each of these functions are designed to work on values of type Boolean.
|
||||||
|
|
||||||
|
|
||||||
[.function]
|
[.function]
|
||||||
|
@ -480,6 +480,37 @@ ${filename:toLower():equals( ${filename} ):or(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[.function]
|
||||||
|
=== ifElse
|
||||||
|
|
||||||
|
*Description*: [.description]#Evaluates the first argument if the Subject evaluates to true, or the second argument
|
||||||
|
if the Subject evaluates to false.#
|
||||||
|
|
||||||
|
*Subject Type*: [.subject]#Boolean#
|
||||||
|
|
||||||
|
*Arguments*:
|
||||||
|
|
||||||
|
- [.argName]#_EvaluateIfTrue_# : [.argDesc]#The value to return if the Subject is true#
|
||||||
|
- [.argName]#_EvaluateIfFalse_# : [.argDesc]#The value to return if the Subject is false#
|
||||||
|
|
||||||
|
*Return Type*: [.returnType]#String#
|
||||||
|
|
||||||
|
*Examples*: If the "filename" attribute has the value "a brand new filename.txt", the "nullFilename" attribute has
|
||||||
|
the value null, and the "bool" attribute has the value "true", then the following expressions will provide
|
||||||
|
the following results:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.ifElse Examples
|
||||||
|
|===================================================================
|
||||||
|
| Expression | Value
|
||||||
|
| `${bool:ifElse('a','b')}` | `a`
|
||||||
|
| `${literal(true):ifElse('a','b')}` | `a`
|
||||||
|
| `${nullFilename:isNull():ifElse('file does not exist', 'located file')}` | `file does not exist`
|
||||||
|
| `${nullFilename:ifElse('found', 'not_found')}` | `not_found`
|
||||||
|
| `${filename:ifElse('found', 'not_found')}` | `not_found`
|
||||||
|
| `${filename:isNull():not():ifElse('found', 'not_found')}` | `found`
|
||||||
|
|===================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -963,10 +994,6 @@ Expressions will provide the following results:
|
||||||
will return 0.
|
will return 0.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[encode]]
|
[[encode]]
|
||||||
== Encode/Decode Functions
|
== Encode/Decode Functions
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue