Merge pull request #5 from apache/develop

Merging latest Apache NiFi develop branch
This commit is contained in:
Brian Ghigiarelli 2015-06-22 09:21:58 -04:00
commit e5444aa3cf
64 changed files with 548 additions and 289 deletions

View File

@ -150,6 +150,7 @@ TO_RADIX : 'toRadix';
OR : 'or';
AND : 'and';
JOIN : 'join';
TO_LITERAL : 'literal';
// 2 arg functions
SUBSTRING : 'substring';

View File

@ -127,7 +127,8 @@ functionCall : functionRef ->
booleanLiteral : TRUE | FALSE;
zeroArgStandaloneFunction : (IP | UUID | NOW | NEXT_INT | HOSTNAME) LPAREN! RPAREN!;
oneArgStandaloneFunction : HOSTNAME^ LPAREN! booleanLiteral RPAREN!;
oneArgStandaloneFunction : (TO_LITERAL^ LPAREN! anyArg RPAREN!) |
(HOSTNAME^ LPAREN! booleanLiteral RPAREN!);
standaloneFunction : zeroArgStandaloneFunction | oneArgStandaloneFunction;
attributeRefOrFunctionCall : (attributeRef | standaloneFunction);

View File

@ -95,12 +95,14 @@ import org.apache.nifi.attribute.expression.language.evaluation.functions.UuidEv
import org.apache.nifi.attribute.expression.language.evaluation.literals.BooleanLiteralEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.literals.NumberLiteralEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.literals.StringLiteralEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.literals.ToLiteralEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.reduce.CountEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.reduce.JoinEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.reduce.ReduceEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.selection.AllAttributesEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.selection.AnyAttributeEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.selection.DelineatedAttributeEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.selection.IteratingEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.selection.MultiAttributeEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.selection.MultiMatchAttributeEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.selection.MultiNamedAttributeEvaluator;
@ -114,6 +116,7 @@ import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.tree.Tree;
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_MATCHING_ATTRIBUTES;
@ -171,6 +174,7 @@ import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpre
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING_BEFORE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING_BEFORE_LAST;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_DATE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_LITERAL;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_LOWER;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_NUMBER;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_RADIX;
@ -181,6 +185,7 @@ import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpre
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.URL_DECODE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.URL_ENCODE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UUID;
import org.apache.nifi.attribute.expression.language.evaluation.selection.MappingEvaluator;
/**
@ -205,7 +210,7 @@ public class Query {
try {
validateExpression(value, false);
return true;
} catch (final ProcessException e) {
} catch (final AttributeExpressionLanguageParsingException | ProcessException e) {
return false;
}
}
@ -341,7 +346,7 @@ public class Query {
if (c == '\\') {
backslashCount++;
} else if (c == quoteChar && ((backslashCount % 2 == 0) || lastChar != '\\')) {
} else if (c == quoteChar && (backslashCount % 2 == 0 || lastChar != '\\')) {
return i;
}
@ -359,7 +364,7 @@ public class Query {
final String value = evaluated.toString();
final String escaped = value.replace("$$", "$");
return (decorator == null) ? escaped : decorator.decorate(escaped);
return decorator == null ? escaped : decorator.decorate(escaped);
}
static String evaluateExpressions(final String rawValue, Map<String, String> expressionMap) throws ProcessException {
@ -631,6 +636,25 @@ public class Query {
}
private static 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();
@ -691,7 +715,7 @@ public class Query {
return "Query [" + query + "]";
}
private static StringEvaluator newStringLiteralEvaluator(final String literalValue) {
private static Evaluator<String> newStringLiteralEvaluator(final String literalValue) {
if (literalValue == null || literalValue.length() < 2) {
return new StringLiteralEvaluator(literalValue);
}
@ -724,7 +748,7 @@ public class Query {
return toStringEvaluator(evaluators.get(0));
}
StringEvaluator lastEvaluator = toStringEvaluator(evaluators.get(0));
Evaluator<String> lastEvaluator = toStringEvaluator(evaluators.get(0));
for (int i = 1; i < evaluators.size(); i++) {
lastEvaluator = new AppendEvaluator(lastEvaluator, toStringEvaluator(evaluators.get(i)));
}
@ -749,8 +773,8 @@ public class Query {
final Tree functionTypeTree = tree.getChild(0);
final int multiAttrType = functionTypeTree.getType();
if (multiAttrType == ANY_DELINEATED_VALUE || multiAttrType == ALL_DELINEATED_VALUES) {
final StringEvaluator delineatedValueEvaluator = toStringEvaluator(buildEvaluator(tree.getChild(1)));
final StringEvaluator delimiterEvaluator = toStringEvaluator(buildEvaluator(tree.getChild(2)));
final Evaluator<String> delineatedValueEvaluator = toStringEvaluator(buildEvaluator(tree.getChild(1)));
final Evaluator<String> delimiterEvaluator = toStringEvaluator(buildEvaluator(tree.getChild(2)));
return new DelineatedAttributeEvaluator(delineatedValueEvaluator, delimiterEvaluator, multiAttrType);
}
@ -807,6 +831,10 @@ public class Query {
case NOW: {
return new NowEvaluator();
}
case TO_LITERAL: {
final Evaluator<?> argEvaluator = buildEvaluator(tree.getChild(0));
return new ToLiteralEvaluator(argEvaluator);
}
case IP: {
try {
return new IPEvaluator();
@ -818,7 +846,7 @@ public class Query {
if (tree.getChildCount() == 0) {
try {
return new HostnameEvaluator(false);
} catch (UnknownHostException e) {
} catch (final UnknownHostException e) {
throw new AttributeExpressionLanguageException(e);
}
} else if (tree.getChildCount() == 1) {
@ -832,7 +860,7 @@ public class Query {
default:
throw new AttributeExpressionLanguageParsingException("Call to hostname() must take 0 or 1 (boolean) parameter");
}
} catch (UnknownHostException e) {
} catch (final UnknownHostException e) {
throw new AttributeExpressionLanguageException(e);
}
} else {
@ -847,16 +875,22 @@ public class Query {
}
}
private static <T> Evaluator<T> addToken(final Evaluator<T> evaluator, final String token) {
evaluator.setToken(token);
return evaluator;
}
private static Evaluator<Boolean> buildBooleanEvaluator(final Tree tree) {
switch (tree.getType()) {
case TRUE:
return new BooleanLiteralEvaluator(true);
return addToken(new BooleanLiteralEvaluator(true), "true");
case FALSE:
return new BooleanLiteralEvaluator(false);
return addToken(new BooleanLiteralEvaluator(false), "true");
}
throw new AttributeExpressionLanguageParsingException("Cannot build Boolean evaluator from tree " + tree.toString());
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static Evaluator<?> buildExpressionEvaluator(final Tree tree) {
if (tree.getChildCount() == 0) {
throw new AttributeExpressionLanguageParsingException("EXPRESSION tree node has no children");
@ -901,6 +935,27 @@ public class Query {
break;
}
}
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;
}
}
}
@ -934,24 +989,25 @@ public class Query {
return args;
}
private static StringEvaluator toStringEvaluator(final Evaluator<?> evaluator) {
private static Evaluator<String> toStringEvaluator(final Evaluator<?> evaluator) {
return toStringEvaluator(evaluator, null);
}
private static StringEvaluator toStringEvaluator(final Evaluator<?> evaluator, final String location) {
private static Evaluator<String> toStringEvaluator(final Evaluator<?> evaluator, final String location) {
if (evaluator.getResultType() == ResultType.STRING) {
return (StringEvaluator) evaluator;
}
return new StringCastEvaluator(evaluator);
return addToken(new StringCastEvaluator(evaluator), evaluator.getToken());
}
private static BooleanEvaluator toBooleanEvaluator(final Evaluator<?> evaluator, final String location) {
@SuppressWarnings("unchecked")
private static Evaluator<Boolean> toBooleanEvaluator(final Evaluator<?> evaluator, final String location) {
switch (evaluator.getResultType()) {
case BOOLEAN:
return (BooleanEvaluator) evaluator;
return (Evaluator<Boolean>) evaluator;
case STRING:
return new BooleanCastEvaluator((StringEvaluator) evaluator);
return addToken(new BooleanCastEvaluator((StringEvaluator) evaluator), evaluator.getToken());
default:
throw new AttributeExpressionLanguageParsingException("Cannot implicitly convert Data Type " + evaluator.getResultType() + " to " + ResultType.BOOLEAN
+ (location == null ? "" : " at location [" + location + "]"));
@ -959,22 +1015,23 @@ public class Query {
}
private static BooleanEvaluator toBooleanEvaluator(final Evaluator<?> evaluator) {
private static Evaluator<Boolean> toBooleanEvaluator(final Evaluator<?> evaluator) {
return toBooleanEvaluator(evaluator, null);
}
private static NumberEvaluator toNumberEvaluator(final Evaluator<?> evaluator) {
private static Evaluator<Long> toNumberEvaluator(final Evaluator<?> evaluator) {
return toNumberEvaluator(evaluator, null);
}
private static NumberEvaluator toNumberEvaluator(final Evaluator<?> evaluator, final String location) {
@SuppressWarnings("unchecked")
private static Evaluator<Long> toNumberEvaluator(final Evaluator<?> evaluator, final String location) {
switch (evaluator.getResultType()) {
case NUMBER:
return (NumberEvaluator) evaluator;
return (Evaluator<Long>) evaluator;
case STRING:
return new NumberCastEvaluator(evaluator);
return addToken(new NumberCastEvaluator(evaluator), evaluator.getToken());
case DATE:
return new DateToNumberEvaluator((DateEvaluator) evaluator);
return addToken(new DateToNumberEvaluator((DateEvaluator) evaluator), evaluator.getToken());
default:
throw new AttributeExpressionLanguageParsingException("Cannot implicitly convert Data Type " + evaluator.getResultType() + " to " + ResultType.NUMBER
+ (location == null ? "" : " at location [" + location + "]"));
@ -997,233 +1054,233 @@ public class Query {
switch (tree.getType()) {
case TRIM: {
verifyArgCount(argEvaluators, 0, "trim");
return new TrimEvaluator(toStringEvaluator(subjectEvaluator));
return addToken(new TrimEvaluator(toStringEvaluator(subjectEvaluator)), "trim");
}
case TO_STRING: {
verifyArgCount(argEvaluators, 0, "toString");
return new ToStringEvaluator(subjectEvaluator);
return addToken(new ToStringEvaluator(subjectEvaluator), "toString");
}
case TO_LOWER: {
verifyArgCount(argEvaluators, 0, "toLower");
return new ToLowerEvaluator(toStringEvaluator(subjectEvaluator));
return addToken(new ToLowerEvaluator(toStringEvaluator(subjectEvaluator)), "toLower");
}
case TO_UPPER: {
verifyArgCount(argEvaluators, 0, "toUpper");
return new ToUpperEvaluator(toStringEvaluator(subjectEvaluator));
return addToken(new ToUpperEvaluator(toStringEvaluator(subjectEvaluator)), "toUpper");
}
case URL_ENCODE: {
verifyArgCount(argEvaluators, 0, "urlEncode");
return new UrlEncodeEvaluator(toStringEvaluator(subjectEvaluator));
return addToken(new UrlEncodeEvaluator(toStringEvaluator(subjectEvaluator)), "urlEncode");
}
case URL_DECODE: {
verifyArgCount(argEvaluators, 0, "urlDecode");
return new UrlDecodeEvaluator(toStringEvaluator(subjectEvaluator));
return addToken(new UrlDecodeEvaluator(toStringEvaluator(subjectEvaluator)), "urlDecode");
}
case SUBSTRING_BEFORE: {
verifyArgCount(argEvaluators, 1, "substringBefore");
return new SubstringBeforeEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to substringBefore"));
return addToken(new SubstringBeforeEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to substringBefore")), "substringBefore");
}
case SUBSTRING_BEFORE_LAST: {
verifyArgCount(argEvaluators, 1, "substringBeforeLast");
return new SubstringBeforeLastEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to substringBeforeLast"));
return addToken(new SubstringBeforeLastEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to substringBeforeLast")), "substringBeforeLast");
}
case SUBSTRING_AFTER: {
verifyArgCount(argEvaluators, 1, "substringAfter");
return new SubstringAfterEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to substringAfter"));
return addToken(new SubstringAfterEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to substringAfter")), "substringAfter");
}
case SUBSTRING_AFTER_LAST: {
verifyArgCount(argEvaluators, 1, "substringAfterLast");
return new SubstringAfterLastEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to substringAfterLast"));
return addToken(new SubstringAfterLastEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to substringAfterLast")), "substringAfterLast");
}
case REPLACE_NULL: {
verifyArgCount(argEvaluators, 1, "replaceNull");
return new ReplaceNullEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to replaceNull"));
return addToken(new ReplaceNullEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to replaceNull")), "replaceNull");
}
case REPLACE_EMPTY: {
verifyArgCount(argEvaluators, 1, "replaceEmtpy");
return new ReplaceEmptyEvaluator(toStringEvaluator(subjectEvaluator), toStringEvaluator(argEvaluators.get(0), "first argumen to replaceEmpty"));
return addToken(new ReplaceEmptyEvaluator(toStringEvaluator(subjectEvaluator), toStringEvaluator(argEvaluators.get(0), "first argument to replaceEmpty")), "replaceEmpty");
}
case REPLACE: {
verifyArgCount(argEvaluators, 2, "replace");
return new ReplaceEvaluator(toStringEvaluator(subjectEvaluator),
return addToken(new ReplaceEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to replace"),
toStringEvaluator(argEvaluators.get(1), "second argument to replace"));
toStringEvaluator(argEvaluators.get(1), "second argument to replace")), "replace");
}
case REPLACE_ALL: {
verifyArgCount(argEvaluators, 2, "replaceAll");
return new ReplaceAllEvaluator(toStringEvaluator(subjectEvaluator),
return addToken(new ReplaceAllEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to replaceAll"),
toStringEvaluator(argEvaluators.get(1), "second argument to replaceAll"));
toStringEvaluator(argEvaluators.get(1), "second argument to replaceAll")), "replaceAll");
}
case APPEND: {
verifyArgCount(argEvaluators, 1, "append");
return new AppendEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to append"));
return addToken(new AppendEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to append")), "append");
}
case PREPEND: {
verifyArgCount(argEvaluators, 1, "prepend");
return new PrependEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to prepend"));
return addToken(new PrependEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to prepend")), "prepend");
}
case SUBSTRING: {
final int numArgs = argEvaluators.size();
if (numArgs == 1) {
return new SubstringEvaluator(toStringEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to substring"));
return addToken(new SubstringEvaluator(toStringEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to substring")), "substring");
} else if (numArgs == 2) {
return new SubstringEvaluator(toStringEvaluator(subjectEvaluator),
return addToken(new SubstringEvaluator(toStringEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to substring"),
toNumberEvaluator(argEvaluators.get(1), "second argument to substring"));
toNumberEvaluator(argEvaluators.get(1), "second argument to substring")), "substring");
} else {
throw new AttributeExpressionLanguageParsingException("substring() function can take either 1 or 2 arguments but cannot take " + numArgs + " arguments");
}
}
case JOIN: {
verifyArgCount(argEvaluators, 1, "join");
return new JoinEvaluator(toStringEvaluator(subjectEvaluator), toStringEvaluator(argEvaluators.get(0)));
return addToken(new JoinEvaluator(toStringEvaluator(subjectEvaluator), toStringEvaluator(argEvaluators.get(0))), "join");
}
case COUNT: {
verifyArgCount(argEvaluators, 0, "count");
return new CountEvaluator(subjectEvaluator);
return addToken(new CountEvaluator(subjectEvaluator), "count");
}
case IS_NULL: {
verifyArgCount(argEvaluators, 0, "isNull");
return new IsNullEvaluator(toStringEvaluator(subjectEvaluator));
return addToken(new IsNullEvaluator(toStringEvaluator(subjectEvaluator)), "isNull");
}
case IS_EMPTY: {
verifyArgCount(argEvaluators, 0, "isNull");
return new IsEmptyEvaluator(toStringEvaluator(subjectEvaluator));
return addToken(new IsEmptyEvaluator(toStringEvaluator(subjectEvaluator)), "isEmpty");
}
case NOT_NULL: {
verifyArgCount(argEvaluators, 0, "notNull");
return new NotNullEvaluator(toStringEvaluator(subjectEvaluator));
return addToken(new NotNullEvaluator(toStringEvaluator(subjectEvaluator)), "notNull");
}
case STARTS_WITH: {
verifyArgCount(argEvaluators, 1, "startsWith");
return new StartsWithEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to startsWith"));
return addToken(new StartsWithEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to startsWith")), "startsWith");
}
case ENDS_WITH: {
verifyArgCount(argEvaluators, 1, "endsWith");
return new EndsWithEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to endsWith"));
return addToken(new EndsWithEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to endsWith")), "endsWith");
}
case CONTAINS: {
verifyArgCount(argEvaluators, 1, "contains");
return new ContainsEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to contains"));
return addToken(new ContainsEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to contains")), "contains");
}
case FIND: {
verifyArgCount(argEvaluators, 1, "find");
return new FindEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to find"));
return addToken(new FindEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to find")), "find");
}
case MATCHES: {
verifyArgCount(argEvaluators, 1, "matches");
return new MatchesEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to matches"));
return addToken(new MatchesEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to matches")), "matches");
}
case EQUALS: {
verifyArgCount(argEvaluators, 1, "equals");
return new EqualsEvaluator(subjectEvaluator, argEvaluators.get(0));
return addToken(new EqualsEvaluator(subjectEvaluator, argEvaluators.get(0)), "equals");
}
case EQUALS_IGNORE_CASE: {
verifyArgCount(argEvaluators, 1, "equalsIgnoreCase");
return new EqualsIgnoreCaseEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to equalsIgnoreCase"));
return addToken(new EqualsIgnoreCaseEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to equalsIgnoreCase")), "equalsIgnoreCase");
}
case GREATER_THAN: {
verifyArgCount(argEvaluators, 1, "gt");
return new GreaterThanEvaluator(toNumberEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to gt"));
return addToken(new GreaterThanEvaluator(toNumberEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to gt")), "gt");
}
case GREATER_THAN_OR_EQUAL: {
verifyArgCount(argEvaluators, 1, "ge");
return new GreaterThanOrEqualEvaluator(toNumberEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to ge"));
return addToken(new GreaterThanOrEqualEvaluator(toNumberEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to ge")), "ge");
}
case LESS_THAN: {
verifyArgCount(argEvaluators, 1, "lt");
return new LessThanEvaluator(toNumberEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to lt"));
return addToken(new LessThanEvaluator(toNumberEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to lt")), "lt");
}
case LESS_THAN_OR_EQUAL: {
verifyArgCount(argEvaluators, 1, "le");
return new LessThanOrEqualEvaluator(toNumberEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to le"));
return addToken(new LessThanOrEqualEvaluator(toNumberEvaluator(subjectEvaluator),
toNumberEvaluator(argEvaluators.get(0), "first argument to le")), "le");
}
case LENGTH: {
verifyArgCount(argEvaluators, 0, "length");
return new LengthEvaluator(toStringEvaluator(subjectEvaluator));
return addToken(new LengthEvaluator(toStringEvaluator(subjectEvaluator)), "length");
}
case TO_DATE: {
if (argEvaluators.isEmpty()) {
return new NumberToDateEvaluator(toNumberEvaluator(subjectEvaluator));
return addToken(new NumberToDateEvaluator(toNumberEvaluator(subjectEvaluator)), "toDate");
} else if (subjectEvaluator.getResultType() == ResultType.STRING) {
return new StringToDateEvaluator(toStringEvaluator(subjectEvaluator), toStringEvaluator(argEvaluators.get(0)));
return addToken(new StringToDateEvaluator(toStringEvaluator(subjectEvaluator), toStringEvaluator(argEvaluators.get(0))), "toDate");
} else {
return new NumberToDateEvaluator(toNumberEvaluator(subjectEvaluator));
return addToken(new NumberToDateEvaluator(toNumberEvaluator(subjectEvaluator)), "toDate");
}
}
case TO_NUMBER: {
verifyArgCount(argEvaluators, 0, "toNumber");
switch (subjectEvaluator.getResultType()) {
case STRING:
return new ToNumberEvaluator((StringEvaluator) subjectEvaluator);
return addToken(new ToNumberEvaluator((StringEvaluator) subjectEvaluator), "toNumber");
case DATE:
return new DateToNumberEvaluator((DateEvaluator) subjectEvaluator);
return addToken(new DateToNumberEvaluator((DateEvaluator) subjectEvaluator), "toNumber");
default:
throw new AttributeExpressionLanguageParsingException(subjectEvaluator + " returns type " + subjectEvaluator.getResultType() + " but expected to get " + ResultType.STRING);
}
}
case TO_RADIX: {
if (argEvaluators.size() == 1) {
return new ToRadixEvaluator((NumberEvaluator) subjectEvaluator, toNumberEvaluator(argEvaluators.get(0)));
return addToken(new ToRadixEvaluator((NumberEvaluator) subjectEvaluator, toNumberEvaluator(argEvaluators.get(0))), "toRadix");
} else {
return new ToRadixEvaluator((NumberEvaluator) subjectEvaluator, toNumberEvaluator(argEvaluators.get(0)), toNumberEvaluator(argEvaluators.get(1)));
return addToken(new ToRadixEvaluator((NumberEvaluator) subjectEvaluator, toNumberEvaluator(argEvaluators.get(0)), toNumberEvaluator(argEvaluators.get(1))), "toRadix");
}
}
case MOD: {
return new ModEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0)));
return addToken(new ModEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0))), "mod");
}
case PLUS: {
return new PlusEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0)));
return addToken(new PlusEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0))), "plus");
}
case MINUS: {
return new MinusEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0)));
return addToken(new MinusEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0))), "minus");
}
case MULTIPLY: {
return new MultiplyEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0)));
return addToken(new MultiplyEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0))), "multiply");
}
case DIVIDE: {
return new DivideEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0)));
return addToken(new DivideEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0))), "divide");
}
case INDEX_OF: {
verifyArgCount(argEvaluators, 1, "indexOf");
return new IndexOfEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to indexOf"));
return addToken(new IndexOfEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to indexOf")), "indexOf");
}
case LAST_INDEX_OF: {
verifyArgCount(argEvaluators, 1, "lastIndexOf");
return new LastIndexOfEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to lastIndexOf"));
return addToken(new LastIndexOfEvaluator(toStringEvaluator(subjectEvaluator),
toStringEvaluator(argEvaluators.get(0), "first argument to lastIndexOf")), "lastIndexOf");
}
case FORMAT: {
return new FormatEvaluator(toDateEvaluator(subjectEvaluator), toStringEvaluator(argEvaluators.get(0), "first argument of format"));
return addToken(new FormatEvaluator(toDateEvaluator(subjectEvaluator), toStringEvaluator(argEvaluators.get(0), "first argument of format")), "format");
}
case OR: {
return new OrEvaluator(toBooleanEvaluator(subjectEvaluator), toBooleanEvaluator(argEvaluators.get(0)));
return addToken(new OrEvaluator(toBooleanEvaluator(subjectEvaluator), toBooleanEvaluator(argEvaluators.get(0))), "or");
}
case AND: {
return new AndEvaluator(toBooleanEvaluator(subjectEvaluator), toBooleanEvaluator(argEvaluators.get(0)));
return addToken(new AndEvaluator(toBooleanEvaluator(subjectEvaluator), toBooleanEvaluator(argEvaluators.get(0))), "and");
}
case NOT: {
return new NotEvaluator(toBooleanEvaluator(subjectEvaluator));
return addToken(new NotEvaluator(toBooleanEvaluator(subjectEvaluator)), "not");
}
default:
throw new AttributeExpressionLanguageParsingException("Expected a Function-type expression but got " + tree.toString());

View File

@ -19,6 +19,7 @@ package org.apache.nifi.attribute.expression.language.evaluation;
import org.apache.nifi.expression.AttributeExpression.ResultType;
public abstract class BooleanEvaluator implements Evaluator<Boolean> {
private String token;
@Override
public ResultType getResultType() {
@ -29,4 +30,14 @@ public abstract class BooleanEvaluator implements Evaluator<Boolean> {
public int getEvaluationsRemaining() {
return 0;
}
@Override
public String getToken() {
return token;
}
@Override
public void setToken(final String token) {
this.token = token;
}
}

View File

@ -21,6 +21,7 @@ import java.util.Date;
import org.apache.nifi.expression.AttributeExpression.ResultType;
public abstract class DateEvaluator implements Evaluator<Date> {
private String token;
@Override
public ResultType getResultType() {
@ -31,4 +32,14 @@ public abstract class DateEvaluator implements Evaluator<Date> {
public int getEvaluationsRemaining() {
return 0;
}
@Override
public String getToken() {
return token;
}
@Override
public void setToken(final String token) {
this.token = token;
}
}

View File

@ -29,4 +29,16 @@ public interface Evaluator<T> {
int getEvaluationsRemaining();
Evaluator<?> getSubjectEvaluator();
/**
* Sets the token that was used in the query to cause this Evaluator to be created
*
* @param token the token that caused this Evaluator to be created
*/
void setToken(String token);
/**
* @return the token that caused this Evaluator to be created
*/
String getToken();
}

View File

@ -19,6 +19,7 @@ package org.apache.nifi.attribute.expression.language.evaluation;
import org.apache.nifi.expression.AttributeExpression.ResultType;
public abstract class NumberEvaluator implements Evaluator<Long> {
private String token;
@Override
public ResultType getResultType() {
@ -30,4 +31,13 @@ public abstract class NumberEvaluator implements Evaluator<Long> {
return 0;
}
@Override
public String getToken() {
return token;
}
@Override
public void setToken(final String token) {
this.token = token;
}
}

View File

@ -19,6 +19,7 @@ package org.apache.nifi.attribute.expression.language.evaluation;
import org.apache.nifi.expression.AttributeExpression.ResultType;
public abstract class StringEvaluator implements Evaluator<String> {
private String token;
@Override
public ResultType getResultType() {
@ -29,4 +30,14 @@ public abstract class StringEvaluator implements Evaluator<String> {
public int getEvaluationsRemaining() {
return 0;
}
@Override
public String getToken() {
return token;
}
@Override
public void setToken(final String token) {
this.token = token;
}
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class AndEvaluator extends BooleanEvaluator {
private final BooleanEvaluator subjectEvaluator;
private final BooleanEvaluator rhsEvaluator;
private final Evaluator<Boolean> subjectEvaluator;
private final Evaluator<Boolean> rhsEvaluator;
public AndEvaluator(final BooleanEvaluator subjectEvaluator, final BooleanEvaluator rhsEvaluator) {
public AndEvaluator(final Evaluator<Boolean> subjectEvaluator, final Evaluator<Boolean> rhsEvaluator) {
this.subjectEvaluator = subjectEvaluator;
this.rhsEvaluator = rhsEvaluator;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class AppendEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final StringEvaluator appendEvaluator;
private final Evaluator<String> subject;
private final Evaluator<String> appendEvaluator;
public AppendEvaluator(final StringEvaluator subject, final StringEvaluator append) {
public AppendEvaluator(final Evaluator<String> subject, final Evaluator<String> append) {
this.subject = subject;
this.appendEvaluator = append;
}

View File

@ -25,9 +25,9 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class AttributeEvaluator extends StringEvaluator {
private final StringEvaluator nameEvaluator;
private final Evaluator<String> nameEvaluator;
public AttributeEvaluator(final StringEvaluator nameEvaluator) {
public AttributeEvaluator(final Evaluator<String> nameEvaluator) {
this.nameEvaluator = nameEvaluator;
}

View File

@ -22,14 +22,13 @@ import org.apache.nifi.attribute.expression.language.evaluation.BooleanEvaluator
import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResult;
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;
public class ContainsEvaluator extends BooleanEvaluator {
private final StringEvaluator subject;
private final StringEvaluator search;
private final Evaluator<String> subject;
private final Evaluator<String> search;
public ContainsEvaluator(final StringEvaluator subject, final StringEvaluator search) {
public ContainsEvaluator(final Evaluator<String> subject, final Evaluator<String> search) {
this.subject = subject;
this.search = search;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class DivideEvaluator extends NumberEvaluator {
private final NumberEvaluator subject;
private final NumberEvaluator divideValue;
private final Evaluator<Long> subject;
private final Evaluator<Long> divideValue;
public DivideEvaluator(final NumberEvaluator subject, final NumberEvaluator divideValue) {
public DivideEvaluator(final Evaluator<Long> subject, final Evaluator<Long> divideValue) {
this.subject = subject;
this.divideValue = divideValue;
}

View File

@ -22,14 +22,13 @@ import org.apache.nifi.attribute.expression.language.evaluation.BooleanEvaluator
import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResult;
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;
public class EndsWithEvaluator extends BooleanEvaluator {
private final StringEvaluator subject;
private final StringEvaluator search;
private final Evaluator<String> subject;
private final Evaluator<String> search;
public EndsWithEvaluator(final StringEvaluator subject, final StringEvaluator search) {
public EndsWithEvaluator(final Evaluator<String> subject, final Evaluator<String> search) {
this.subject = subject;
this.search = search;
}

View File

@ -23,17 +23,16 @@ import org.apache.nifi.attribute.expression.language.evaluation.BooleanEvaluator
import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResult;
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.literals.StringLiteralEvaluator;
public class FindEvaluator extends BooleanEvaluator {
private final StringEvaluator subject;
private final StringEvaluator search;
private final Evaluator<String> subject;
private final Evaluator<String> search;
private final Pattern compiledPattern;
public FindEvaluator(final StringEvaluator subject, final StringEvaluator search) {
public FindEvaluator(final Evaluator<String> subject, final Evaluator<String> search) {
this.subject = subject;
this.search = search;

View File

@ -30,9 +30,9 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class FormatEvaluator extends StringEvaluator {
private final DateEvaluator subject;
private final StringEvaluator format;
private final Evaluator<String> format;
public FormatEvaluator(final DateEvaluator subject, final StringEvaluator format) {
public FormatEvaluator(final DateEvaluator subject, final Evaluator<String> format) {
this.subject = subject;
this.format = format;
}

View File

@ -21,15 +21,14 @@ import java.util.Map;
import org.apache.nifi.attribute.expression.language.evaluation.BooleanEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class GreaterThanEvaluator extends BooleanEvaluator {
private final NumberEvaluator subject;
private final NumberEvaluator comparison;
private final Evaluator<Long> subject;
private final Evaluator<Long> comparison;
public GreaterThanEvaluator(final NumberEvaluator subject, final NumberEvaluator comparison) {
public GreaterThanEvaluator(final Evaluator<Long> subject, final Evaluator<Long> comparison) {
this.subject = subject;
this.comparison = comparison;
}

View File

@ -21,15 +21,14 @@ import java.util.Map;
import org.apache.nifi.attribute.expression.language.evaluation.BooleanEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class GreaterThanOrEqualEvaluator extends BooleanEvaluator {
private final NumberEvaluator subject;
private final NumberEvaluator comparison;
private final Evaluator<Long> subject;
private final Evaluator<Long> comparison;
public GreaterThanOrEqualEvaluator(final NumberEvaluator subject, final NumberEvaluator comparison) {
public GreaterThanOrEqualEvaluator(final Evaluator<Long> subject, final Evaluator<Long> comparison) {
this.subject = subject;
this.comparison = comparison;
}

View File

@ -22,14 +22,13 @@ import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberQueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator;
public class IndexOfEvaluator extends NumberEvaluator {
private final StringEvaluator subject;
private final StringEvaluator indexEvaluator;
private final Evaluator<String> subject;
private final Evaluator<String> indexEvaluator;
public IndexOfEvaluator(final StringEvaluator subject, final StringEvaluator indexEvaluator) {
public IndexOfEvaluator(final Evaluator<String> subject, final Evaluator<String> indexEvaluator) {
this.subject = subject;
this.indexEvaluator = indexEvaluator;
}

View File

@ -22,14 +22,13 @@ import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberQueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator;
public class LastIndexOfEvaluator extends NumberEvaluator {
private final StringEvaluator subject;
private final StringEvaluator indexEvaluator;
private final Evaluator<String> subject;
private final Evaluator<String> indexEvaluator;
public LastIndexOfEvaluator(final StringEvaluator subject, final StringEvaluator indexEvaluator) {
public LastIndexOfEvaluator(final Evaluator<String> subject, final Evaluator<String> indexEvaluator) {
this.subject = subject;
this.indexEvaluator = indexEvaluator;
}

View File

@ -22,20 +22,19 @@ import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberQueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator;
public class LengthEvaluator extends NumberEvaluator {
private final StringEvaluator subject;
private final Evaluator<String> subject;
public LengthEvaluator(final StringEvaluator subject) {
public LengthEvaluator(final Evaluator<String> subject) {
this.subject = subject;
}
@Override
public QueryResult<Long> evaluate(final Map<String, String> attributes) {
final String subjectValue = subject.evaluate(attributes).getValue();
return new NumberQueryResult((long) ((subjectValue == null) ? 0 : subjectValue.length()));
return new NumberQueryResult((long) (subjectValue == null ? 0 : subjectValue.length()));
}
@Override

View File

@ -21,15 +21,14 @@ import java.util.Map;
import org.apache.nifi.attribute.expression.language.evaluation.BooleanEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class LessThanEvaluator extends BooleanEvaluator {
private final NumberEvaluator subject;
private final NumberEvaluator comparison;
private final Evaluator<Long> subject;
private final Evaluator<Long> comparison;
public LessThanEvaluator(final NumberEvaluator subject, final NumberEvaluator comparison) {
public LessThanEvaluator(final Evaluator<Long> subject, final Evaluator<Long> comparison) {
this.subject = subject;
this.comparison = comparison;
}

View File

@ -21,15 +21,14 @@ import java.util.Map;
import org.apache.nifi.attribute.expression.language.evaluation.BooleanEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class LessThanOrEqualEvaluator extends BooleanEvaluator {
private final NumberEvaluator subject;
private final NumberEvaluator comparison;
private final Evaluator<Long> subject;
private final Evaluator<Long> comparison;
public LessThanOrEqualEvaluator(final NumberEvaluator subject, final NumberEvaluator comparison) {
public LessThanOrEqualEvaluator(final Evaluator<Long> subject, final Evaluator<Long> comparison) {
this.subject = subject;
this.comparison = comparison;
}

View File

@ -23,17 +23,16 @@ import org.apache.nifi.attribute.expression.language.evaluation.BooleanEvaluator
import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResult;
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.literals.StringLiteralEvaluator;
public class MatchesEvaluator extends BooleanEvaluator {
private final StringEvaluator subject;
private final StringEvaluator search;
private final Evaluator<String> subject;
private final Evaluator<String> search;
private final Pattern compiledPattern;
public MatchesEvaluator(final StringEvaluator subject, final StringEvaluator search) {
public MatchesEvaluator(final Evaluator<String> subject, final Evaluator<String> search) {
this.subject = subject;
this.search = search;

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class MinusEvaluator extends NumberEvaluator {
private final NumberEvaluator subject;
private final NumberEvaluator minusValue;
private final Evaluator<Long> subject;
private final Evaluator<Long> minusValue;
public MinusEvaluator(final NumberEvaluator subject, final NumberEvaluator minusValue) {
public MinusEvaluator(final Evaluator<Long> subject, final Evaluator<Long> minusValue) {
this.subject = subject;
this.minusValue = minusValue;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class ModEvaluator extends NumberEvaluator {
private final NumberEvaluator subject;
private final NumberEvaluator modValue;
private final Evaluator<Long> subject;
private final Evaluator<Long> modValue;
public ModEvaluator(final NumberEvaluator subject, final NumberEvaluator modValue) {
public ModEvaluator(final Evaluator<Long> subject, final Evaluator<Long> modValue) {
this.subject = subject;
this.modValue = modValue;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class MultiplyEvaluator extends NumberEvaluator {
private final NumberEvaluator subject;
private final NumberEvaluator multiplyValue;
private final Evaluator<Long> subject;
private final Evaluator<Long> multiplyValue;
public MultiplyEvaluator(final NumberEvaluator subject, final NumberEvaluator multiplyValue) {
public MultiplyEvaluator(final Evaluator<Long> subject, final Evaluator<Long> multiplyValue) {
this.subject = subject;
this.multiplyValue = multiplyValue;
}

View File

@ -25,9 +25,9 @@ import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class NotEvaluator extends BooleanEvaluator {
private final BooleanEvaluator subjectEvaluator;
private final Evaluator<Boolean> subjectEvaluator;
public NotEvaluator(final BooleanEvaluator subjectEvaluator) {
public NotEvaluator(final Evaluator<Boolean> subjectEvaluator) {
this.subjectEvaluator = subjectEvaluator;
}

View File

@ -22,14 +22,13 @@ import java.util.Map;
import org.apache.nifi.attribute.expression.language.evaluation.DateEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.DateQueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class NumberToDateEvaluator extends DateEvaluator {
private final NumberEvaluator subject;
private final Evaluator<Long> subject;
public NumberToDateEvaluator(final NumberEvaluator subject) {
public NumberToDateEvaluator(final Evaluator<Long> subject) {
this.subject = subject;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class OrEvaluator extends BooleanEvaluator {
private final BooleanEvaluator subjectEvaluator;
private final BooleanEvaluator rhsEvaluator;
private final Evaluator<Boolean> subjectEvaluator;
private final Evaluator<Boolean> rhsEvaluator;
public OrEvaluator(final BooleanEvaluator subjectEvaluator, final BooleanEvaluator rhsEvaluator) {
public OrEvaluator(final Evaluator<Boolean> subjectEvaluator, final Evaluator<Boolean> rhsEvaluator) {
this.subjectEvaluator = subjectEvaluator;
this.rhsEvaluator = rhsEvaluator;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class PlusEvaluator extends NumberEvaluator {
private final NumberEvaluator subject;
private final NumberEvaluator plusValue;
private final Evaluator<Long> subject;
private final Evaluator<Long> plusValue;
public PlusEvaluator(final NumberEvaluator subject, final NumberEvaluator plusValue) {
public PlusEvaluator(final Evaluator<Long> subject, final Evaluator<Long> plusValue) {
this.subject = subject;
this.plusValue = plusValue;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class PrependEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final StringEvaluator prependEvaluator;
private final Evaluator<String> subject;
private final Evaluator<String> prependEvaluator;
public PrependEvaluator(final StringEvaluator subject, final StringEvaluator prepend) {
public PrependEvaluator(final Evaluator<String> subject, final Evaluator<String> prepend) {
this.subject = subject;
this.prependEvaluator = prepend;
}

View File

@ -25,11 +25,11 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class ReplaceAllEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final StringEvaluator search;
private final StringEvaluator replacement;
private final Evaluator<String> subject;
private final Evaluator<String> search;
private final Evaluator<String> replacement;
public ReplaceAllEvaluator(final StringEvaluator subject, final StringEvaluator search, final StringEvaluator replacement) {
public ReplaceAllEvaluator(final Evaluator<String> subject, final Evaluator<String> search, final Evaluator<String> replacement) {
this.subject = subject;
this.search = search;
this.replacement = replacement;

View File

@ -24,10 +24,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator;
public class ReplaceEmptyEvaluator extends StringEvaluator {
private final StringEvaluator subjectEvaluator;
private final StringEvaluator replacementEvaluator;
private final Evaluator<String> subjectEvaluator;
private final Evaluator<String> replacementEvaluator;
public ReplaceEmptyEvaluator(final StringEvaluator subjectEvaluator, final StringEvaluator replacementEvaluator) {
public ReplaceEmptyEvaluator(final Evaluator<String> subjectEvaluator, final Evaluator<String> replacementEvaluator) {
this.subjectEvaluator = subjectEvaluator;
this.replacementEvaluator = replacementEvaluator;
}

View File

@ -25,11 +25,11 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class ReplaceEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final StringEvaluator search;
private final StringEvaluator replacement;
private final Evaluator<String> subject;
private final Evaluator<String> search;
private final Evaluator<String> replacement;
public ReplaceEvaluator(final StringEvaluator subject, final StringEvaluator search, final StringEvaluator replacement) {
public ReplaceEvaluator(final Evaluator<String> subject, final Evaluator<String> search, final Evaluator<String> replacement) {
this.subject = subject;
this.search = search;
this.replacement = replacement;

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class ReplaceNullEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final StringEvaluator resultEvaluator;
private final Evaluator<String> subject;
private final Evaluator<String> resultEvaluator;
public ReplaceNullEvaluator(final StringEvaluator subject, final StringEvaluator resultEvaluator) {
public ReplaceNullEvaluator(final Evaluator<String> subject, final Evaluator<String> resultEvaluator) {
this.subject = subject;
this.resultEvaluator = resultEvaluator;
}

View File

@ -22,14 +22,13 @@ import org.apache.nifi.attribute.expression.language.evaluation.BooleanEvaluator
import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResult;
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;
public class StartsWithEvaluator extends BooleanEvaluator {
private final StringEvaluator subject;
private final StringEvaluator search;
private final Evaluator<String> subject;
private final Evaluator<String> search;
public StartsWithEvaluator(final StringEvaluator subject, final StringEvaluator search) {
public StartsWithEvaluator(final Evaluator<String> subject, final Evaluator<String> search) {
this.subject = subject;
this.search = search;
}

View File

@ -26,15 +26,14 @@ import org.apache.nifi.attribute.expression.language.evaluation.DateEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.DateQueryResult;
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.exception.IllegalAttributeException;
public class StringToDateEvaluator extends DateEvaluator {
private final StringEvaluator subject;
private final StringEvaluator format;
private final Evaluator<String> subject;
private final Evaluator<String> format;
public StringToDateEvaluator(final StringEvaluator subject, final StringEvaluator format) {
public StringToDateEvaluator(final Evaluator<String> subject, final Evaluator<String> format) {
this.subject = subject;
this.format = format;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class SubstringAfterEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final StringEvaluator afterEvaluator;
private final Evaluator<String> subject;
private final Evaluator<String> afterEvaluator;
public SubstringAfterEvaluator(final StringEvaluator subject, final StringEvaluator afterEvaluator) {
public SubstringAfterEvaluator(final Evaluator<String> subject, final Evaluator<String> afterEvaluator) {
this.subject = subject;
this.afterEvaluator = afterEvaluator;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class SubstringAfterLastEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final StringEvaluator afterEvaluator;
private final Evaluator<String> subject;
private final Evaluator<String> afterEvaluator;
public SubstringAfterLastEvaluator(final StringEvaluator subject, final StringEvaluator afterEvaluator) {
public SubstringAfterLastEvaluator(final Evaluator<String> subject, final Evaluator<String> afterEvaluator) {
this.subject = subject;
this.afterEvaluator = afterEvaluator;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class SubstringBeforeEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final StringEvaluator beforeEvaluator;
private final Evaluator<String> subject;
private final Evaluator<String> beforeEvaluator;
public SubstringBeforeEvaluator(final StringEvaluator subject, final StringEvaluator beforeEvaluator) {
public SubstringBeforeEvaluator(final Evaluator<String> subject, final Evaluator<String> beforeEvaluator) {
this.subject = subject;
this.beforeEvaluator = beforeEvaluator;
}

View File

@ -25,10 +25,10 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class SubstringBeforeLastEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final StringEvaluator beforeEvaluator;
private final Evaluator<String> subject;
private final Evaluator<String> beforeEvaluator;
public SubstringBeforeLastEvaluator(final StringEvaluator subject, final StringEvaluator beforeEvaluator) {
public SubstringBeforeLastEvaluator(final Evaluator<String> subject, final Evaluator<String> beforeEvaluator) {
this.subject = subject;
this.beforeEvaluator = beforeEvaluator;
}

View File

@ -19,24 +19,23 @@ package org.apache.nifi.attribute.expression.language.evaluation.functions;
import java.util.Map;
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
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;
public class SubstringEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final NumberEvaluator startIndex;
private final NumberEvaluator endIndex;
private final Evaluator<String> subject;
private final Evaluator<Long> startIndex;
private final Evaluator<Long> endIndex;
public SubstringEvaluator(final StringEvaluator subject, final NumberEvaluator startIndex, final NumberEvaluator endIndex) {
public SubstringEvaluator(final Evaluator<String> subject, final Evaluator<Long> startIndex, final Evaluator<Long> endIndex) {
this.subject = subject;
this.startIndex = startIndex;
this.endIndex = endIndex;
}
public SubstringEvaluator(final StringEvaluator subject, final NumberEvaluator startIndex) {
public SubstringEvaluator(final Evaluator<String> subject, final Evaluator<Long> startIndex) {
this.subject = subject;
this.startIndex = startIndex;
this.endIndex = null;

View File

@ -25,16 +25,16 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class ToLowerEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final Evaluator<String> subject;
public ToLowerEvaluator(final StringEvaluator subject) {
public ToLowerEvaluator(final Evaluator<String> subject) {
this.subject = subject;
}
@Override
public QueryResult<String> evaluate(final Map<String, String> attributes) {
final String subjectValue = subject.evaluate(attributes).getValue();
return new StringQueryResult((subjectValue == null) ? null : subjectValue.toLowerCase());
return new StringQueryResult(subjectValue == null ? null : subjectValue.toLowerCase());
}
@Override

View File

@ -22,20 +22,19 @@ import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberQueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator;
public class ToNumberEvaluator extends NumberEvaluator {
private final StringEvaluator subject;
private final Evaluator<String> subject;
public ToNumberEvaluator(final StringEvaluator subject) {
public ToNumberEvaluator(final Evaluator<String> subject) {
this.subject = subject;
}
@Override
public QueryResult<Long> evaluate(final Map<String, String> attributes) {
final String subjectValue = subject.evaluate(attributes).getValue();
return new NumberQueryResult((subjectValue == null || subjectValue.trim().isEmpty()) ? null : Long.valueOf(subjectValue));
return new NumberQueryResult(subjectValue == null || subjectValue.trim().isEmpty() ? null : Long.valueOf(subjectValue));
}
@Override

View File

@ -20,22 +20,21 @@ import java.util.Arrays;
import java.util.Map;
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
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;
public class ToRadixEvaluator extends StringEvaluator {
private final NumberEvaluator numberEvaluator;
private final NumberEvaluator radixEvaluator;
private final NumberEvaluator minimumWidthEvaluator;
private final Evaluator<Long> numberEvaluator;
private final Evaluator<Long> radixEvaluator;
private final Evaluator<Long> minimumWidthEvaluator;
public ToRadixEvaluator(final NumberEvaluator subject, final NumberEvaluator radixEvaluator) {
public ToRadixEvaluator(final Evaluator<Long> subject, final Evaluator<Long> radixEvaluator) {
this(subject, radixEvaluator, null);
}
public ToRadixEvaluator(final NumberEvaluator subject, final NumberEvaluator radixEvaluator, final NumberEvaluator minimumWidthEvaluator) {
public ToRadixEvaluator(final Evaluator<Long> subject, final Evaluator<Long> radixEvaluator, final Evaluator<Long> minimumWidthEvaluator) {
this.numberEvaluator = subject;
this.radixEvaluator = radixEvaluator;
this.minimumWidthEvaluator = minimumWidthEvaluator;

View File

@ -25,16 +25,16 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class ToUpperEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final Evaluator<String> subject;
public ToUpperEvaluator(final StringEvaluator subject) {
public ToUpperEvaluator(final Evaluator<String> subject) {
this.subject = subject;
}
@Override
public QueryResult<String> evaluate(final Map<String, String> attributes) {
final String subjectValue = subject.evaluate(attributes).getValue();
return new StringQueryResult((subjectValue == null) ? null : subjectValue.toUpperCase());
return new StringQueryResult(subjectValue == null ? null : subjectValue.toUpperCase());
}
@Override

View File

@ -25,9 +25,9 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class TrimEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final Evaluator<String> subject;
public TrimEvaluator(final StringEvaluator subject) {
public TrimEvaluator(final Evaluator<String> subject) {
this.subject = subject;
}

View File

@ -27,9 +27,9 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class UrlDecodeEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final Evaluator<String> subject;
public UrlDecodeEvaluator(final StringEvaluator subject) {
public UrlDecodeEvaluator(final Evaluator<String> subject) {
this.subject = subject;
}
@ -42,7 +42,7 @@ public class UrlDecodeEvaluator extends StringEvaluator {
try {
return new StringQueryResult(URLDecoder.decode(subjectValue, "UTF-8"));
} catch (UnsupportedEncodingException e) {
} catch (final UnsupportedEncodingException e) {
return null; // won't happen. It's UTF-8
}
}

View File

@ -27,9 +27,9 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class UrlEncodeEvaluator extends StringEvaluator {
private final StringEvaluator subject;
private final Evaluator<String> subject;
public UrlEncodeEvaluator(final StringEvaluator subject) {
public UrlEncodeEvaluator(final Evaluator<String> subject) {
this.subject = subject;
}
@ -42,7 +42,7 @@ public class UrlEncodeEvaluator extends StringEvaluator {
try {
return new StringQueryResult(URLEncoder.encode(subjectValue, "UTF-8"));
} catch (UnsupportedEncodingException e) {
} catch (final UnsupportedEncodingException e) {
return null; // won't happen. It's UTF-8
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.literals;
import java.util.Map;
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;
public class ToLiteralEvaluator extends StringEvaluator {
private final Evaluator<?> argEvaluator;
public ToLiteralEvaluator(final Evaluator<?> argEvaluator) {
this.argEvaluator = argEvaluator;
}
@Override
public QueryResult<String> evaluate(final Map<String, String> attributes) {
final Object result = argEvaluator.evaluate(attributes);
return new StringQueryResult(result == null ? null : result.toString());
}
@Override
public Evaluator<?> getSubjectEvaluator() {
return null;
}
}

View File

@ -25,13 +25,13 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResul
public class JoinEvaluator extends StringEvaluator implements ReduceEvaluator<String> {
private final StringEvaluator subjectEvaluator;
private final StringEvaluator delimiterEvaluator;
private final Evaluator<String> subjectEvaluator;
private final Evaluator<String> delimiterEvaluator;
private final StringBuilder sb = new StringBuilder();
private int evalCount = 0;
public JoinEvaluator(final StringEvaluator subject, final StringEvaluator delimiter) {
public JoinEvaluator(final Evaluator<String> subject, final Evaluator<String> delimiter) {
this.subjectEvaluator = subject;
this.delimiterEvaluator = delimiter;
}

View File

@ -23,7 +23,7 @@ import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResu
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class AllAttributesEvaluator extends BooleanEvaluator {
public class AllAttributesEvaluator extends BooleanEvaluator implements IteratingEvaluator<Boolean> {
private final BooleanEvaluator booleanEvaluator;
private final MultiAttributeEvaluator multiAttributeEvaluator;
@ -65,4 +65,9 @@ public class AllAttributesEvaluator extends BooleanEvaluator {
public Evaluator<?> getSubjectEvaluator() {
return null;
}
@Override
public Evaluator<?> getLogicEvaluator() {
return booleanEvaluator;
}
}

View File

@ -23,7 +23,7 @@ import org.apache.nifi.attribute.expression.language.evaluation.BooleanQueryResu
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
public class AnyAttributeEvaluator extends BooleanEvaluator {
public class AnyAttributeEvaluator extends BooleanEvaluator implements IteratingEvaluator<Boolean> {
private final BooleanEvaluator booleanEvaluator;
private final MultiAttributeEvaluator multiAttributeEvaluator;
@ -65,4 +65,9 @@ public class AnyAttributeEvaluator extends BooleanEvaluator {
public Evaluator<?> getSubjectEvaluator() {
return null;
}
@Override
public Evaluator<Boolean> getLogicEvaluator() {
return booleanEvaluator;
}
}

View File

@ -20,19 +20,18 @@ import java.util.Map;
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;
public class DelineatedAttributeEvaluator extends MultiAttributeEvaluator {
private final StringEvaluator subjectEvaluator;
private final StringEvaluator delimiterEvaluator;
private final Evaluator<String> subjectEvaluator;
private final Evaluator<String> delimiterEvaluator;
private final int evaluationType;
private String[] delineatedValues;
private int evaluationCount = 0;
private int evaluationsLeft = 1;
public DelineatedAttributeEvaluator(final StringEvaluator subjectEvaluator, final StringEvaluator delimiterEvaluator, final int evaluationType) {
public DelineatedAttributeEvaluator(final Evaluator<String> subjectEvaluator, final Evaluator<String> delimiterEvaluator, final int evaluationType) {
this.subjectEvaluator = subjectEvaluator;
this.delimiterEvaluator = delimiterEvaluator;
this.evaluationType = evaluationType;
@ -66,6 +65,11 @@ public class DelineatedAttributeEvaluator extends MultiAttributeEvaluator {
return new StringQueryResult(delineatedValues[evaluationCount++]);
}
@Override
public Evaluator<?> getLogicEvaluator() {
return subjectEvaluator;
}
@Override
public int getEvaluationsRemaining() {
return evaluationsLeft;

View File

@ -1,21 +1,33 @@
/*
* 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.selection;
public class AnyMatchingAttributeEvaluator {
}
/*
* 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.selection;
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
/**
* Interface for an Evaluator that should be evaluated multiple times
*
* @param <T> return type of evaluator
*/
public interface IteratingEvaluator<T> extends Evaluator<T> {
/**
* @return the evaluator that evaluates some sort of logic against its subject
*/
Evaluator<?> getLogicEvaluator();
}

View File

@ -24,9 +24,9 @@ import org.apache.nifi.attribute.expression.language.evaluation.reduce.ReduceEva
import org.apache.nifi.expression.AttributeExpression.ResultType;
public class MappingEvaluator<T> implements Evaluator<T> {
private final ReduceEvaluator<T> mappingEvaluator;
private final MultiAttributeEvaluator multiAttributeEvaluator;
private String token;
public MappingEvaluator(final ReduceEvaluator<T> mappingEvaluator, final MultiAttributeEvaluator multiAttributeEval) {
this.mappingEvaluator = mappingEvaluator;
@ -59,4 +59,13 @@ public class MappingEvaluator<T> implements Evaluator<T> {
return null;
}
@Override
public String getToken() {
return token;
}
@Override
public void setToken(final String token) {
this.token = token;
}
}

View File

@ -18,7 +18,6 @@ package org.apache.nifi.attribute.expression.language.evaluation.selection;
import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator;
public abstract class MultiAttributeEvaluator extends StringEvaluator {
public abstract class MultiAttributeEvaluator extends StringEvaluator implements IteratingEvaluator<String> {
public abstract int getEvaluationType();
}

View File

@ -79,4 +79,9 @@ public class MultiMatchAttributeEvaluator extends MultiAttributeEvaluator {
public int getEvaluationType() {
return evaluationType;
}
@Override
public Evaluator<?> getLogicEvaluator() {
return this;
}
}

View File

@ -61,4 +61,9 @@ public class MultiNamedAttributeEvaluator extends MultiAttributeEvaluator {
public int getEvaluationType() {
return evaluationType;
}
@Override
public Evaluator<?> getLogicEvaluator() {
return this;
}
}

View File

@ -17,10 +17,12 @@
package org.apache.nifi.attribute.expression.language;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@ -52,6 +54,8 @@ public class TestQuery {
assertValid("${now():format('yyyy/MM/dd')}");
assertInvalid("${attr:times(3)}");
assertValid("${attr:toNumber():multiply(3)}");
assertValid("${hostname()}");
assertValid("${literal(3)}");
// left here because it's convenient for looking at the output
//System.out.println(Query.compile("").evaluate(null));
}
@ -296,7 +300,7 @@ public class TestQuery {
}
private String evaluateQueryForEscape(final String queryString, final Map<String, String> attributes) {
FlowFile mockFlowFile = Mockito.mock(FlowFile.class);
final FlowFile mockFlowFile = Mockito.mock(FlowFile.class);
Mockito.when(mockFlowFile.getAttributes()).thenReturn(attributes);
Mockito.when(mockFlowFile.getId()).thenReturn(1L);
Mockito.when(mockFlowFile.getEntryDate()).thenReturn(System.currentTimeMillis());
@ -429,7 +433,7 @@ public class TestQuery {
@Test
public void testExtractExpressionTypes() {
List<ResultType> types = Query.extractResultTypes("${hello:equals( ${goodbye} )} or just hi, ${bob}, are you ${bob.age:toNumber()} yet? $$$${bob}");
final List<ResultType> types = Query.extractResultTypes("${hello:equals( ${goodbye} )} or just hi, ${bob}, are you ${bob.age:toNumber()} yet? $$$${bob}");
assertEquals(3, types.size());
assertEquals(ResultType.BOOLEAN, types.get(0));
assertEquals(ResultType.STRING, types.get(1));
@ -493,7 +497,7 @@ public class TestQuery {
final Map<String, String> attributes = new HashMap<>();
attributes.put("xx", "say 'hi'");
String query = "${xx:replace( \"'hi'\", '\\\"hello\\\"' )}";
final String query = "${xx:replace( \"'hi'\", '\\\"hello\\\"' )}";
System.out.println(query);
verifyEquals(query, attributes, "say \"hello\"");
}
@ -1112,12 +1116,52 @@ public class TestQuery {
assertEquals("{ xyz }", Query.evaluateExpressions(query, attributes));
}
@Test
public void testLiteralFunction() {
final Map<String, String> attrs = Collections.<String, String> emptyMap();
verifyEquals("${literal(2):gt(1)}", attrs, true);
verifyEquals("${literal('hello'):substring(0, 1):equals('h')}", attrs, true);
}
@Test
public void testFunctionAfterReduce() {
// Cannot call gt(2) after count() because count() is a 'reducing function'
// and must be the last function in an expression.
assertFalse(Query.isValidExpression("${allMatchingAttributes('a.*'):contains('2'):count():gt(2)}"));
final Map<String, String> attributes = new HashMap<>();
attributes.put("a.1", "245");
attributes.put("a.2", "123");
attributes.put("a.3", "732");
attributes.put("a.4", "343");
attributes.put("a.5", "553");
final String endsWithCount = "${allMatchingAttributes('a.*'):contains('2'):count()}";
assertTrue(Query.isValidExpression(endsWithCount));
verifyEquals(endsWithCount, attributes, 3L);
// in order to check if value is greater than 2, need to first evaluate the
// 'aggregate' and 'reducing' functions as an inner expression. Then we can
// use the literal() function to make the result of the inner expression the subject
// of the function gt()
final String usingLiteral = "${literal(" + endsWithCount + "):gt(2)}";
assertTrue(Query.isValidExpression(usingLiteral));
verifyEquals(usingLiteral, attributes, true);
attributes.clear();
attributes.put("a1", "123");
attributes.put("a2", "321");
verifyEquals("${allMatchingAttributes('a.*'):contains('2')}", attributes, true);
verifyEquals("${allMatchingAttributes('a.*'):contains('2'):toUpper():equals('TRUE')}", attributes, true);
verifyEquals("${allMatchingAttributes('a.*'):contains('2'):equals('true'):and( ${literal(true)} )}", attributes, true);
}
private void verifyEquals(final String expression, final Map<String, String> attributes, final Object expectedResult) {
Query.validateExpression(expression, false);
assertEquals(String.valueOf(expectedResult), Query.evaluateExpressions(expression, attributes, null));
Query query = Query.compile(expression);
QueryResult<?> result = query.evaluate(attributes);
final Query query = Query.compile(expression);
final QueryResult<?> result = query.evaluate(attributes);
if (expectedResult instanceof Number) {
assertEquals(ResultType.NUMBER, result.getResultType());

View File

@ -1317,9 +1317,9 @@ Expressions will provide the following results:
and Midnight GMT on January 1, 2014. The Expression `${time:toDate("yyyy/MM/dd HH:mm:ss.SSS'Z'")}` will result in the
number of milliseconds between Midnight GMT on January 1, 1970 and 15:36:03.264 GMT on December 31, 2014.
Often, this function is used in conjunction with the <<format>> function to change the format of a date/time. For example,
if the attribute "date" has the value "12-24-2014" and we want to change the format to "2014/12/24", we can do so by
chaining together the two functions: `${date:toDate('MM-dd-yyyy'):format('yyyy/MM/dd')}`.
Often, this function is used in conjunction with the <<format>> function to change the format of a date/time. For example,
if the attribute "date" has the value "12-24-2014" and we want to change the format to "2014/12/24", we can do so by
chaining together the two functions: `${date:toDate('MM-dd-yyyy'):format('yyyy/MM/dd')}`.
@ -1404,7 +1404,7 @@ an error when validating the function.
*Return Type*: [.returnType]#String#
*Examples*: The IP address of the machine can be obtained by using the Expresison `${ip()}`.
*Examples*: The IP address of the machine can be obtained by using the Expression `${ip()}`.
@ -1471,8 +1471,26 @@ an error when validating the function.
[.function]
=== literal
*Description*: [.description]#Returns its argument as a literal String value. This is useful in order to treat a string or a number
at the beginning of an Expression as an actual value, rather than treating it as an attribute name. Additionally, it
can be used when the argument is an embedded Expression that we would then like to evaluate additional functions against.#
*Subject Type*: [.subjectless]#No Subject#
*Arguments*:
- [.argName]#_value_# : [.argDesc]#The value to be treated as a literal string, number, or boolean value.#
*Return Type*: [.returnType]#String#
*Examples*: `${literal(2):gt(1)}` returns `true`
`${literal( ${allMatchingAttributes('a.*'):count()} ):gt(3)}` returns true if there are more than 3 attributes whose
names begin with the letter `a`.
[[multi]]
== Evaluating Multiple Attributes

View File

@ -89,7 +89,7 @@ import org.xml.sax.InputSource;
+ "Name into which the result will be placed (if the Destination is flowfile-attribute; otherwise, the property name is ignored). "
+ "The value of the property must be a valid XPath expression. If the XPath evaluates to more than one node and the Return Type is "
+ "set to 'nodeset' (either directly, or via 'auto-detect' with a Destination of "
+ "'flowfile-content', the FlowFile will be unmodified and will be routed to failure. If the XPath does not "
+ "'flowfile-content'), the FlowFile will be unmodified and will be routed to failure. If the XPath does not "
+ "evaluate to a Node, the FlowFile will be routed to 'unmatched' without having its contents modified. If Destination is "
+ "flowfile-attribute and the expression matches nothing, attributes will be created with empty strings as the value, and the "
+ "FlowFile will always be routed to 'matched'")

View File

@ -67,9 +67,10 @@ import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.nifi.annotation.behavior.WritesAttribute;
import org.apache.nifi.annotation.behavior.WritesAttributes;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.annotation.behavior.WritesAttribute;
import org.apache.nifi.annotation.lifecycle.OnShutdown;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.ValidationContext;
@ -91,7 +92,10 @@ import org.apache.nifi.util.StopWatch;
@Tags({"get", "fetch", "poll", "http", "https", "ingest", "source", "input"})
@CapabilityDescription("Fetches a file via HTTP")
@WritesAttribute(attribute = "filename", description = "the filename is set to the name of the file on the remote server")
@WritesAttributes({
@WritesAttribute(attribute = "filename", description = "The filename is set to the name of the file on the remote server"),
@WritesAttribute(attribute = "mime.type", description = "The MIME Type of the FlowFile, as reported by the HTTP Content-Type header")
})
public class GetHTTP extends AbstractSessionFactoryProcessor {
static final int PERSISTENCE_INTERVAL_MSEC = 10000;
@ -413,6 +417,15 @@ public class GetHTTP extends AbstractSessionFactoryProcessor {
flowFile = session.putAttribute(flowFile, CoreAttributes.FILENAME.key(), context.getProperty(FILENAME).getValue());
flowFile = session.putAttribute(flowFile, this.getClass().getSimpleName().toLowerCase() + ".remote.source", source);
flowFile = session.importFrom(response.getEntity().getContent(), flowFile);
final Header contentTypeHeader = response.getFirstHeader("Content-Type");
if (contentTypeHeader != null) {
final String contentType = contentTypeHeader.getValue();
if (!contentType.trim().isEmpty()) {
flowFile = session.putAttribute(flowFile, CoreAttributes.MIME_TYPE.key(), contentType.trim());
}
}
final long flowFileSize = flowFile.getSize();
stopWatch.stop();
final String dataRate = stopWatch.calculateDataRate(flowFileSize);