diff --git a/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/AsyncLineageSubmission.java b/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/AsyncLineageSubmission.java index dc24a93fe4..4a52a89bbf 100644 --- a/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/AsyncLineageSubmission.java +++ b/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/AsyncLineageSubmission.java @@ -27,6 +27,7 @@ import org.apache.nifi.provenance.lineage.LineageComputationType; * */ public class AsyncLineageSubmission implements ComputeLineageSubmission { + private final String lineageIdentifier = UUID.randomUUID().toString(); private final Date submissionTime = new Date(); diff --git a/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/AsyncQuerySubmission.java b/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/AsyncQuerySubmission.java index 42444762be..00c617052f 100644 --- a/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/AsyncQuerySubmission.java +++ b/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/AsyncQuerySubmission.java @@ -22,9 +22,6 @@ import java.util.concurrent.TimeUnit; import org.apache.nifi.provenance.search.Query; import org.apache.nifi.provenance.search.QuerySubmission; -/** - * - */ public class AsyncQuerySubmission implements QuerySubmission { public static final int TTL = (int) TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS); @@ -40,8 +37,8 @@ public class AsyncQuerySubmission implements QuerySubmission { * number of steps, indicating how many results must be added to this * AsyncQuerySubmission before it is considered finished * - * @param query - * @param numSteps + * @param query the query to execute + * @param numSteps how many steps to include */ public AsyncQuerySubmission(final Query query, final int numSteps) { this.query = query; diff --git a/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/SearchableFields.java b/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/SearchableFields.java index 97c988029a..de62bca813 100644 --- a/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/SearchableFields.java +++ b/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/SearchableFields.java @@ -41,14 +41,21 @@ public class SearchableFields { public static final SearchableField Details = new NamedSearchableField("Details", "details", "Details", false, SearchableFieldType.STRING); public static final SearchableField Relationship = new NamedSearchableField("Relationship", "relationship", "Relationship", false, SearchableFieldType.STRING); - public static final SearchableField LineageStartDate = new NamedSearchableField("LineageStartDate", "lineageStartDate", "Lineage Start Date", false, SearchableFieldType.DATE); - public static final SearchableField LineageIdentifier = new NamedSearchableField("LineageIdentifiers", "lineageIdentifier", "Lineage Identifier", false, SearchableFieldType.STRING); + public static final SearchableField LineageStartDate + = new NamedSearchableField("LineageStartDate", "lineageStartDate", "Lineage Start Date", false, SearchableFieldType.DATE); + public static final SearchableField LineageIdentifier + = new NamedSearchableField("LineageIdentifiers", "lineageIdentifier", "Lineage Identifier", false, SearchableFieldType.STRING); - public static final SearchableField ContentClaimSection = new NamedSearchableField("ContentClaimSection", "contentClaimSection", "Content Claim Section", false, SearchableFieldType.STRING); - public static final SearchableField ContentClaimContainer = new NamedSearchableField("ContentClaimContainer", "contentClaimContainer", "Content Claim Container", false, SearchableFieldType.STRING); - public static final SearchableField ContentClaimIdentifier = new NamedSearchableField("ContentClaimIdentifier", "contentClaimIdentifier", "Content Claim Identifier", false, SearchableFieldType.STRING); - public static final SearchableField ContentClaimOffset = new NamedSearchableField("ContentClaimOffset", "contentClaimOffset", "Content Claim Offset", false, SearchableFieldType.LONG); - public static final SearchableField SourceQueueIdentifier = new NamedSearchableField("SourceQueueIdentifier", "sourceQueueIdentifier", "Source Queue Identifier", false, SearchableFieldType.STRING); + public static final SearchableField ContentClaimSection + = new NamedSearchableField("ContentClaimSection", "contentClaimSection", "Content Claim Section", false, SearchableFieldType.STRING); + public static final SearchableField ContentClaimContainer + = new NamedSearchableField("ContentClaimContainer", "contentClaimContainer", "Content Claim Container", false, SearchableFieldType.STRING); + public static final SearchableField ContentClaimIdentifier + = new NamedSearchableField("ContentClaimIdentifier", "contentClaimIdentifier", "Content Claim Identifier", false, SearchableFieldType.STRING); + public static final SearchableField ContentClaimOffset + = new NamedSearchableField("ContentClaimOffset", "contentClaimOffset", "Content Claim Offset", false, SearchableFieldType.LONG); + public static final SearchableField SourceQueueIdentifier + = new NamedSearchableField("SourceQueueIdentifier", "sourceQueueIdentifier", "Source Queue Identifier", false, SearchableFieldType.STRING); private static final Map standardFields; diff --git a/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/StandardLineageResult.java b/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/StandardLineageResult.java index afb56e8bdb..63c53d0635 100644 --- a/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/StandardLineageResult.java +++ b/nifi/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/StandardLineageResult.java @@ -266,7 +266,8 @@ public class StandardLineageResult implements ComputeLineageResult { final FlowFileNode childNode = new FlowFileNode(childUuid, record.getEventTime()); final boolean isNewFlowFile = nodes.add(childNode); if (!isNewFlowFile) { - final String msg = "Unable to generate Lineage Graph because multiple events were registered claiming to have generated the same FlowFile (UUID = " + childNode.getFlowFileUuid() + ")"; + final String msg = "Unable to generate Lineage Graph because multiple " + + "events were registered claiming to have generated the same FlowFile (UUID = " + childNode.getFlowFileUuid() + ")"; logger.error(msg); setError(msg); return; @@ -288,12 +289,13 @@ public class StandardLineageResult implements ComputeLineageResult { break; case RECEIVE: case CREATE: { - // for a receive event, we want to create a FlowFile Node that represents the FlowFile received + // for a receive event, we want to create a FlowFile Node that represents the FlowFile received // and create an edge from the Receive Event to the FlowFile Node final LineageNode flowFileNode = new FlowFileNode(record.getFlowFileUuid(), record.getEventTime()); final boolean isNewFlowFile = nodes.add(flowFileNode); if (!isNewFlowFile) { - final String msg = "Found cycle in graph. This indicates that multiple events were registered claiming to have generated the same FlowFile (UUID = " + flowFileNode.getFlowFileUuid() + ")"; + final String msg = "Found cycle in graph. This indicates that multiple events " + + "were registered claiming to have generated the same FlowFile (UUID = " + flowFileNode.getFlowFileUuid() + ")"; setError(msg); logger.error(msg); return; diff --git a/nifi/nifi-commons/nifi-expression-language/pom.xml b/nifi/nifi-commons/nifi-expression-language/pom.xml index 3521b55ebf..e27f5b1e17 100644 --- a/nifi/nifi-commons/nifi-expression-language/pom.xml +++ b/nifi/nifi-commons/nifi-expression-language/pom.xml @@ -34,6 +34,13 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + + **/antlr/AttributeExpressionParser.java,**/antlr/AttributeExpressionLexer.java + + diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/InvalidPreparedQuery.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/InvalidPreparedQuery.java index e23bcc0972..a29e7922da 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/InvalidPreparedQuery.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/InvalidPreparedQuery.java @@ -23,21 +23,22 @@ import org.apache.nifi.expression.AttributeValueDecorator; import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.processor.exception.ProcessException; - /** - * An implementation of PreparedQuery that throws an {@link AttributeExpressionLanguageException} when attempting - * to evaluate the query. This allows a PreparedQuery to be created, even though it can't - * be evaluated. + * An implementation of PreparedQuery that throws an + * {@link AttributeExpressionLanguageException} when attempting to evaluate the + * query. This allows a PreparedQuery to be created, even though it can't be + * evaluated. */ public class InvalidPreparedQuery implements PreparedQuery { + private final String query; private final String explanation; - + public InvalidPreparedQuery(final String query, final String explanation) { this.query = query; this.explanation = explanation; } - + @Override public String evaluateExpressions(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException { throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation); diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java index 420a8e21c7..7e40897ac9 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java @@ -16,8 +16,6 @@ */ package org.apache.nifi.attribute.expression.language; -import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.*; - import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; @@ -116,6 +114,73 @@ 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; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.AND; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ANY_ATTRIBUTE; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ANY_DELINEATED_VALUE; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ANY_MATCHING_ATTRIBUTE; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.APPEND; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ATTRIBUTE_REFERENCE; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ATTR_NAME; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.CONTAINS; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.COUNT; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.DIVIDE; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ENDS_WITH; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.EQUALS; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.EQUALS_IGNORE_CASE; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.EXPRESSION; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.FALSE; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.FIND; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.FORMAT; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.GREATER_THAN; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.GREATER_THAN_OR_EQUAL; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.HOSTNAME; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.INDEX_OF; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.IP; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.IS_EMPTY; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.IS_NULL; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.JOIN; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.LAST_INDEX_OF; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.LENGTH; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.LESS_THAN; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.LESS_THAN_OR_EQUAL; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MATCHES; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MINUS; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MOD; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MULTIPLY; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MULTI_ATTRIBUTE_REFERENCE; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NEXT_INT; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NOT; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NOT_NULL; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NOW; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NUMBER; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.OR; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.PLUS; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.PREPEND; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.REPLACE; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.REPLACE_ALL; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.REPLACE_EMPTY; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.REPLACE_NULL; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.STARTS_WITH; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.STRING_LITERAL; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING_AFTER; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING_AFTER_LAST; +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_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; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_STRING; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_UPPER; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TRIM; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TRUE; +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; /** @@ -229,11 +294,9 @@ public class Query { } /** - * - * - * @param value - * @param allowSurroundingCharacters - * @throws AttributeExpressionLanguageParsingException + * @param value expression to validate + * @param allowSurroundingCharacters whether to allow surrounding chars + * @throws AttributeExpressionLanguageParsingException if problems parsing given expression */ public static void validateExpression(final String value, final boolean allowSurroundingCharacters) throws AttributeExpressionLanguageParsingException { if (!allowSurroundingCharacters) { @@ -333,8 +396,8 @@ public class Query { /** * Un-escapes ${...} patterns that were escaped * - * @param value - * @return + * @param value to un-escape + * @return un-escaped value */ public static String unescape(final String value) { return value.replaceAll("\\$\\$(?=\\$*\\{.*?\\})", "\\$"); diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/GreaterThanEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/GreaterThanEvaluator.java index 6c712bbda0..af1ee1d13c 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/GreaterThanEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/GreaterThanEvaluator.java @@ -49,9 +49,6 @@ public class GreaterThanEvaluator extends BooleanEvaluator { return new BooleanQueryResult(subjectValue > comparisonValue); } - ; - - @Override public Evaluator getSubjectEvaluator() { return subject; diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/GreaterThanOrEqualEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/GreaterThanOrEqualEvaluator.java index 98951f27e1..1269fc0b0a 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/GreaterThanOrEqualEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/GreaterThanOrEqualEvaluator.java @@ -49,9 +49,6 @@ public class GreaterThanOrEqualEvaluator extends BooleanEvaluator { return new BooleanQueryResult(subjectValue >= comparisonValue); } - ; - - @Override public Evaluator getSubjectEvaluator() { return subject; diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/IsEmptyEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/IsEmptyEvaluator.java index c5e3c2188f..e6e9fc9eb6 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/IsEmptyEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/IsEmptyEvaluator.java @@ -24,12 +24,13 @@ import org.apache.nifi.attribute.expression.language.evaluation.Evaluator; import org.apache.nifi.attribute.expression.language.evaluation.QueryResult; public class IsEmptyEvaluator extends BooleanEvaluator { + private final Evaluator subjectEvaluator; - + public IsEmptyEvaluator(final Evaluator subjectEvaluator) { this.subjectEvaluator = subjectEvaluator; } - + @Override public QueryResult evaluate(final Map attributes) { final Object subjectValue = subjectEvaluator.evaluate(attributes).getValue(); diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/LessThanEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/LessThanEvaluator.java index 9a589103c6..4b1beac776 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/LessThanEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/LessThanEvaluator.java @@ -49,9 +49,6 @@ public class LessThanEvaluator extends BooleanEvaluator { return new BooleanQueryResult(subjectValue < comparisonValue); } - ; - - @Override public Evaluator getSubjectEvaluator() { return subject; diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/LessThanOrEqualEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/LessThanOrEqualEvaluator.java index 10f3f6aad8..a07e8be521 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/LessThanOrEqualEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/LessThanOrEqualEvaluator.java @@ -49,9 +49,6 @@ public class LessThanOrEqualEvaluator extends BooleanEvaluator { return new BooleanQueryResult(subjectValue <= comparisonValue); } - ; - - @Override public Evaluator getSubjectEvaluator() { return subject; diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ReplaceEmptyEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ReplaceEmptyEvaluator.java index e5c40d229b..fe08303e41 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ReplaceEmptyEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ReplaceEmptyEvaluator.java @@ -23,20 +23,21 @@ import org.apache.nifi.attribute.expression.language.evaluation.QueryResult; import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator; public class ReplaceEmptyEvaluator extends StringEvaluator { + private final StringEvaluator subjectEvaluator; private final StringEvaluator replacementEvaluator; - + public ReplaceEmptyEvaluator(final StringEvaluator subjectEvaluator, final StringEvaluator replacementEvaluator) { this.subjectEvaluator = subjectEvaluator; this.replacementEvaluator = replacementEvaluator; } - + @Override public QueryResult evaluate(final Map attributes) { final QueryResult subjectResult = subjectEvaluator.evaluate(attributes); final String subjectValue = subjectResult.getValue(); final boolean isEmpty = subjectValue == null || subjectValue.toString().trim().isEmpty(); - if ( isEmpty ) { + if (isEmpty) { return replacementEvaluator.evaluate(attributes); } else { return subjectResult; diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/CountEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/CountEvaluator.java index f2af268813..f3fb21d638 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/CountEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/CountEvaluator.java @@ -28,19 +28,19 @@ public class CountEvaluator extends NumberEvaluator implements ReduceEvaluator subjectEvaluator; private long count = 0L; - + public CountEvaluator(final Evaluator subjectEvaluator) { this.subjectEvaluator = subjectEvaluator; } - + @Override public QueryResult evaluate(final Map attributes) { final QueryResult result = subjectEvaluator.evaluate(attributes); - if ( result.getValue() == null ) { + if (result.getValue() == null) { return new NumberQueryResult(count); } - - if ( result.getResultType() == ResultType.BOOLEAN && ((Boolean) result.getValue()).equals(Boolean.FALSE) ) { + + if (result.getResultType() == ResultType.BOOLEAN && ((Boolean) result.getValue()).equals(Boolean.FALSE)) { return new NumberQueryResult(count); } diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/JoinEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/JoinEvaluator.java index eefdadad19..81c325da9e 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/JoinEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/JoinEvaluator.java @@ -24,34 +24,35 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResult; public class JoinEvaluator extends StringEvaluator implements ReduceEvaluator { + private final StringEvaluator subjectEvaluator; private final StringEvaluator delimiterEvaluator; - + private final StringBuilder sb = new StringBuilder(); private int evalCount = 0; - + public JoinEvaluator(final StringEvaluator subject, final StringEvaluator delimiter) { this.subjectEvaluator = subject; this.delimiterEvaluator = delimiter; } - + @Override public QueryResult evaluate(final Map attributes) { String subject = subjectEvaluator.evaluate(attributes).getValue(); - if ( subject == null ) { + if (subject == null) { subject = ""; } - + final String delimiter = delimiterEvaluator.evaluate(attributes).getValue(); - if ( evalCount > 0 ) { + if (evalCount > 0) { sb.append(delimiter); } sb.append(subject); evalCount++; - return new StringQueryResult( sb.toString() ); + return new StringQueryResult(sb.toString()); } - + @Override public Evaluator getSubjectEvaluator() { return subjectEvaluator; diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MappingEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MappingEvaluator.java index d872b6e4c2..2b8c488b43 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MappingEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MappingEvaluator.java @@ -24,19 +24,20 @@ import org.apache.nifi.attribute.expression.language.evaluation.reduce.ReduceEva import org.apache.nifi.expression.AttributeExpression.ResultType; public class MappingEvaluator implements Evaluator { + private final ReduceEvaluator mappingEvaluator; private final MultiAttributeEvaluator multiAttributeEvaluator; - + public MappingEvaluator(final ReduceEvaluator mappingEvaluator, final MultiAttributeEvaluator multiAttributeEval) { this.mappingEvaluator = mappingEvaluator; this.multiAttributeEvaluator = multiAttributeEval; } - + @Override public QueryResult evaluate(final Map attributes) { QueryResult result = mappingEvaluator.evaluate(attributes); - while ( multiAttributeEvaluator.getEvaluationsRemaining() > 0 ) { + while (multiAttributeEvaluator.getEvaluationsRemaining() > 0) { result = mappingEvaluator.evaluate(attributes); } diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MultiMatchAttributeEvaluator.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MultiMatchAttributeEvaluator.java index 9a441ce35b..1d0be8bf61 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MultiMatchAttributeEvaluator.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MultiMatchAttributeEvaluator.java @@ -44,7 +44,7 @@ public class MultiMatchAttributeEvaluator extends MultiAttributeEvaluator { /** * Can be called only after the first call to evaluate * - * @return + * @return number of remaining evaluations */ @Override public int getEvaluationsRemaining() { diff --git a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/exception/IllegalAttributeException.java b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/exception/IllegalAttributeException.java index f6f32cac7d..ec94837c75 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/exception/IllegalAttributeException.java +++ b/nifi/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/exception/IllegalAttributeException.java @@ -17,6 +17,7 @@ package org.apache.nifi.attribute.expression.language.exception; public class IllegalAttributeException extends RuntimeException { + private static final long serialVersionUID = 12348721897342L; public IllegalAttributeException() { diff --git a/nifi/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java b/nifi/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java index 8dfbaf16b8..4bf614f0db 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java +++ b/nifi/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java @@ -55,7 +55,7 @@ public class TestQuery { // left here because it's convenient for looking at the output //System.out.println(Query.compile("").evaluate(null)); } - + private void assertValid(final String query) { try { Query.compile(query); @@ -64,7 +64,7 @@ public class TestQuery { Assert.fail("Expected query to be valid, but it failed to compile due to " + e); } } - + private void assertInvalid(final String query) { try { Query.compile(query); @@ -72,63 +72,61 @@ public class TestQuery { } catch (final Exception e) { } } - + @Test public void testIsValidExpression() { Query.validateExpression("${abc:substring(${xyz:length()})}", false); Query.isValidExpression("${now():format('yyyy-MM-dd')}"); - - + try { Query.validateExpression("$${attr}", false); Assert.fail("invalid query validated"); } catch (final AttributeExpressionLanguageParsingException e) { } - + Query.validateExpression("$${attr}", true); - - Query.validateExpression("${filename:startsWith('T8MTXBC')\n" - + ":or( ${filename:startsWith('C4QXABC')} )\n" - + ":or( ${filename:startsWith('U6CXEBC')} )" - + ":or( ${filename:startsWith('KYM3ABC')} )}", false); + + Query.validateExpression("${filename:startsWith('T8MTXBC')\n" + + ":or( ${filename:startsWith('C4QXABC')} )\n" + + ":or( ${filename:startsWith('U6CXEBC')} )" + + ":or( ${filename:startsWith('KYM3ABC')} )}", false); } - @Test public void testCompileEmbedded() { final String expression = "${x:equals( ${y} )}"; final Query query = Query.compile(expression); final Tree tree = query.getTree(); - System.out.println( printTree(tree) ); - + System.out.println(printTree(tree)); + final Map attributes = new HashMap<>(); attributes.put("x", "x"); attributes.put("y", "x"); final String result = Query.evaluateExpressions(expression, attributes, null); assertEquals("true", result); - + Query.validateExpression(expression, false); } - + private String printTree(final Tree tree) { final StringBuilder sb = new StringBuilder(); printTree(tree, 0, sb); - + return sb.toString(); } - + private void printTree(final Tree tree, final int spaces, final StringBuilder sb) { - for (int i=0; i < spaces; i++) { + for (int i = 0; i < spaces; i++) { sb.append(" "); } - - if ( tree.getText().trim().isEmpty() ) { + + if (tree.getText().trim().isEmpty()) { sb.append(tree.toString()).append("\n"); } else { sb.append(tree.getText()).append("\n"); } - - for (int i=0; i < tree.getChildCount(); i++) { + + for (int i = 0; i < tree.getChildCount(); i++) { printTree(tree.getChild(i), spaces + 2, sb); } } @@ -138,7 +136,7 @@ public class TestQuery { final Map attributes = new HashMap<>(); attributes.put("attr", "My Value"); attributes.put("${xx}", "hello"); - + assertEquals("My Value", evaluateQueryForEscape("${attr}", attributes)); assertEquals("${attr}", evaluateQueryForEscape("$${attr}", attributes)); assertEquals("$My Value", evaluateQueryForEscape("$$${attr}", attributes)); @@ -151,15 +149,15 @@ public class TestQuery { final Map attributes = new HashMap<>(); attributes.put("x", "C:\\test\\1.txt"); attributes.put("y", "y\ny"); - + final String query = "${x:substringAfterLast( '/' ):substringAfterLast( '\\\\' )}"; verifyEquals(query, attributes, "1.txt"); attributes.put("x", "C:/test/1.txt"); verifyEquals(query, attributes, "1.txt"); - + verifyEquals("${y:equals('y\\ny')}", attributes, Boolean.TRUE); } - + @Test public void testWithTicksOutside() { final Map attributes = new HashMap<>(); @@ -174,14 +172,13 @@ public class TestQuery { assertEquals("'My Value", Query.evaluateExpressions("'${attr}", attributes, null)); } - @Test @Ignore("Depends on TimeZone") public void testDateToNumber() { final Query query = Query.compile("${dateTime:toDate('yyyy/MM/dd HH:mm:ss.SSS'):toNumber()}"); final Map attributes = new HashMap<>(); attributes.put("dateTime", "2013/11/18 10:22:27.678"); - + final QueryResult result = query.evaluate(attributes); assertEquals(ResultType.NUMBER, result.getResultType()); assertEquals(1384788147678L, result.getValue()); @@ -203,35 +200,34 @@ public class TestQuery { final Query query = Query.compile("${dateTime:format('yyyy/MM/dd HH:mm:ss.SSS')}"); final Map attributes = new HashMap<>(); attributes.put("dateTime", date.toString()); - + // the date.toString() above will end up truncating the milliseconds. So remove millis from the Date before // formatting it final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS", Locale.US); final long millis = date.getTime() % 1000L; final Date roundedToNearestSecond = new Date(date.getTime() - millis); final String formatted = sdf.format(roundedToNearestSecond); - + final QueryResult result = query.evaluate(attributes); assertEquals(ResultType.STRING, result.getResultType()); assertEquals(formatted, result.getValue()); } - @Test public void testEmbeddedExpressionsAndQuotes() { final Map attributes = new HashMap<>(); attributes.put("x", "abc"); attributes.put("a", "abc"); - + verifyEquals("${x:equals(${a})}", attributes, true); - + Query.validateExpression("${x:equals('${a}')}", false); assertEquals("true", Query.evaluateExpressions("${x:equals('${a}')}", attributes, null)); - + Query.validateExpression("${x:equals(\"${a}\")}", false); assertEquals("true", Query.evaluateExpressions("${x:equals(\"${a}\")}", attributes, null)); } - + @Test public void testJoin() { final Map attributes = new HashMap<>(); @@ -243,13 +239,12 @@ public class TestQuery { verifyEquals("${a.a:join(', ')}", attributes, "a"); verifyEquals("${allAttributes( 'x', 'y' ):join(',')}", attributes, ","); } - - @Test(expected=AttributeExpressionLanguageException.class) + + @Test(expected = AttributeExpressionLanguageException.class) public void testCannotCombineWithNonReducingFunction() { Query.compileTree("${allAttributes( 'a.1' ):plus(1)}"); } - @Test public void testIsEmpty() { final Map attributes = new HashMap<>(); @@ -263,22 +258,19 @@ public class TestQuery { verifyEquals("${d:isEmpty()}", attributes, true); } - @Test public void testReplaceEmpty() { final Map attributes = new HashMap<>(); attributes.put("a", "a"); attributes.put("b", ""); attributes.put("c", " \n"); - + verifyEquals("${a:replaceEmpty('c')}", attributes, "a"); verifyEquals("${b:replaceEmpty('c')}", attributes, "c"); verifyEquals("${c:replaceEmpty('c')}", attributes, "c"); verifyEquals("${d:replaceEmpty('c')}", attributes, "c"); } - - @Test public void testCount() { final Map attributes = new HashMap<>(); @@ -291,20 +283,18 @@ public class TestQuery { verifyEquals("${allMatchingAttributes( '.*' ):count()}", attributes, 6L); verifyEquals("${allMatchingAttributes( '.*' ):length():gt(2):count()}", attributes, 5L); - verifyEquals("${allMatchingAttributes( 'n.*' ):plus(1):count()}", attributes, 3L ); + verifyEquals("${allMatchingAttributes( 'n.*' ):plus(1):count()}", attributes, 3L); } - - + @Test public void testCurlyBracesInQuotes() { final Map attributes = new HashMap<>(); attributes.put("attr", "My Valuee"); - + assertEquals("Val", evaluateQueryForEscape("${attr:replaceAll('My (Val)ue{1,2}', '$1')}", attributes)); assertEquals("Val", evaluateQueryForEscape("${attr:replaceAll(\"My (Val)ue{1,2}\", '$1')}", attributes)); } - - + private String evaluateQueryForEscape(final String queryString, final Map attributes) { FlowFile mockFlowFile = Mockito.mock(FlowFile.class); Mockito.when(mockFlowFile.getAttributes()).thenReturn(attributes); @@ -315,15 +305,14 @@ public class TestQuery { Mockito.when(mockFlowFile.getLineageStartDate()).thenReturn(System.currentTimeMillis()); return Query.evaluateExpressions(queryString, mockFlowFile); } - - + @Test public void testGetAttributeValue() { final Map attributes = new HashMap<>(); attributes.put("attr", "My Value"); verifyEquals("${attr}", attributes, "My Value"); } - + @Test public void testGetAttributeValueEmbedded() { final Map attributes = new HashMap<>(); @@ -331,14 +320,14 @@ public class TestQuery { attributes.put("XX", "My Value"); verifyEquals("${${attr:trim()}}", attributes, "My Value"); } - + @Test public void testSimpleSubstring() { final Map attributes = new HashMap<>(); attributes.put("attr", "My Value"); verifyEquals("${attr:substring(2, 5)}", attributes, " Va"); } - + @Test public void testCallToFunctionWithSubjectResultOfAnotherFunctionCall() { final Map attributes = new HashMap<>(); @@ -359,29 +348,28 @@ public class TestQuery { attributes.put("attr", " XX "); verifyEquals("${attr:trim():equals('XX')}", attributes, true); } - + @Test public void testDeeplyEmbedded() { final Map attributes = new HashMap<>(); attributes.put("x", "false"); attributes.put("abc", "a"); attributes.put("a", "a"); - + verifyEquals("${x:or( ${${abc}:length():equals(1)} )}", attributes, true); } - - + @Test public void testExtractExpressionRanges() { List ranges = Query.extractExpressionRanges("hello"); assertTrue(ranges.isEmpty()); - + ranges = Query.extractExpressionRanges("${hello"); assertTrue(ranges.isEmpty()); - + ranges = Query.extractExpressionRanges("hello}"); assertTrue(ranges.isEmpty()); - + ranges = Query.extractExpressionRanges("$${hello"); assertTrue(ranges.isEmpty()); @@ -393,52 +381,50 @@ public class TestQuery { Range range = ranges.get(0); assertEquals(0, range.getStart()); assertEquals(7, range.getEnd()); - + ranges = Query.extractExpressionRanges("${hello:equals( ${goodbye} )}"); assertEquals(1, ranges.size()); range = ranges.get(0); assertEquals(0, range.getStart()); assertEquals(28, range.getEnd()); - + ranges = Query.extractExpressionRanges("${hello:equals( $${goodbye} )}"); assertEquals(1, ranges.size()); range = ranges.get(0); assertEquals(0, range.getStart()); assertEquals(29, range.getEnd()); - + ranges = Query.extractExpressionRanges("${hello:equals( $${goodbye} )} or just hi, ${bob:or(${jerry})}"); assertEquals(2, ranges.size()); range = ranges.get(0); assertEquals(0, range.getStart()); assertEquals(29, range.getEnd()); - + range = ranges.get(1); assertEquals(43, range.getStart()); assertEquals(61, range.getEnd()); - - + ranges = Query.extractExpressionRanges("${hello:equals( ${goodbye} )} or just hi, ${bob}, are you ${bob.age:toNumber()} yet? $$$${bob}"); assertEquals(3, ranges.size()); range = ranges.get(0); assertEquals(0, range.getStart()); assertEquals(28, range.getEnd()); - + range = ranges.get(1); assertEquals(42, range.getStart()); assertEquals(47, range.getEnd()); - + range = ranges.get(2); assertEquals(58, range.getStart()); assertEquals(78, range.getEnd()); - + ranges = Query.extractExpressionRanges("${x:matches( '.{4}' )}"); assertEquals(1, ranges.size()); range = ranges.get(0); assertEquals(0, range.getStart()); assertEquals(21, range.getEnd()); } - - + @Test public void testExtractExpressionTypes() { List types = Query.extractResultTypes("${hello:equals( ${goodbye} )} or just hi, ${bob}, are you ${bob.age:toNumber()} yet? $$$${bob}"); @@ -447,19 +433,18 @@ public class TestQuery { assertEquals(ResultType.STRING, types.get(1)); assertEquals(ResultType.NUMBER, types.get(2)); } - - + @Test public void testEqualsEmbedded() { final Map attributes = new HashMap<>(); attributes.put("x", "hello"); attributes.put("y", "good-bye"); - + verifyEquals("${x:equals( ${y} )}", attributes, false); - + attributes.put("y", "hello"); verifyEquals("${x:equals( ${y} )}", attributes, true); - + attributes.put("x", "4"); attributes.put("y", "3"); attributes.put("z", "1"); @@ -474,18 +459,17 @@ public class TestQuery { attributes.put("y", "88"); assertEquals("true", Query.evaluateExpressions("${x:equals( '${y}' )}", attributes, null)); } - - + @Test public void testComplicatedEmbeddedExpressions() { final Map attributes = new HashMap<>(); attributes.put("fox", "quick, brown"); attributes.put("dog", "lazy"); - + verifyEquals("${fox:substring( ${ 'dog' :substring(2):length()}, 5 ):equals( 'ick' )}", attributes, true); verifyEquals("${fox:substring( ${ 'dog' :substring(2):length()}, 5 ):equals( 'ick' )}", attributes, true); } - + @Test public void testQuotingQuotes() { final Map attributes = new HashMap<>(); @@ -501,7 +485,7 @@ public class TestQuery { System.out.println(query); verifyEquals(query, attributes, "say \"hi\""); } - + @Test public void testDoubleQuotesWithinSingleQuotes() { final Map attributes = new HashMap<>(); @@ -511,30 +495,30 @@ public class TestQuery { System.out.println(query); verifyEquals(query, attributes, "say \"hello\""); } - + @Test public void testEscapeQuotes() { final long timestamp = 1403620278642L; final Map attributes = new HashMap<>(); attributes.put("date", String.valueOf(timestamp)); - + final String format = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; - + final String query = "startDateTime=\"${date:toNumber():toDate():format(\"" + format + "\")}\""; final String result = Query.evaluateExpressions(query, attributes, null); - + final String expectedTime = new SimpleDateFormat(format, Locale.US).format(timestamp); assertEquals("startDateTime=\"" + expectedTime + "\"", result); - + final List ranges = Query.extractExpressionRanges(query); assertEquals(1, ranges.size()); } - + @Test public void testDateConversion() { final Map attributes = new HashMap<>(); attributes.put("date", "1403620278642"); - + verifyEquals("${date:format('yyyy')}", attributes, "2014"); verifyEquals("${date:toDate():format('yyyy')}", attributes, "2014"); verifyEquals("${date:toNumber():format('yyyy')}", attributes, "2014"); @@ -542,17 +526,16 @@ public class TestQuery { verifyEquals("${date:toDate():toNumber():format('yyyy')}", attributes, "2014"); verifyEquals("${date:toDate():toNumber():toDate():toNumber():toDate():toNumber():format('yyyy')}", attributes, "2014"); } - + @Test public void testSingleLetterAttribute() { final Map attributes = new HashMap<>(); attributes.put("A", "0123456789"); - + verifyEquals("${A}", attributes, "0123456789"); verifyEquals("${'A'}", attributes, "0123456789"); } - @Test public void testImplicitConversions() { final Map attributes = new HashMap<>(); @@ -562,7 +545,7 @@ public class TestQuery { attributes.put("d", "Quick Brown Fox"); attributes.put("F", "-48"); attributes.put("n", "2014/04/04 00:00:00"); - + final Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, 2014); cal.set(Calendar.MONTH, 3); @@ -570,11 +553,10 @@ public class TestQuery { cal.set(Calendar.HOUR, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 45); - + final String dateString = cal.getTime().toString(); attributes.put("z", dateString); - verifyEquals("${A:plus(4)}", attributes, 123456793L); verifyEquals("${A:plus( ${F} )}", attributes, 123456741L); @@ -582,11 +564,11 @@ public class TestQuery { verifyEquals("${A:substring(2,3):plus(21):substring(1,2):plus(0)}", attributes, 3L); verifyEquals("${n:format( 'yyyy' )}", attributes, "2014"); verifyEquals("${z:format( 'yyyy' )}", attributes, "2014"); - + attributes.put("n", "2014/04/04 00:00:00.045"); verifyEquals("${n:format( 'yyyy' ):append(','):append( ${n:format( 'SSS' )} )}", attributes, "2014,045"); } - + @Test public void testNewLinesAndTabsInQuery() { final String query = "${ abc:equals('abc'):or( \n\t${xx:isNull()}\n) }"; @@ -594,12 +576,12 @@ public class TestQuery { Query.validateExpression(query, false); assertEquals("true", Query.evaluateExpressions(query)); } - + @Test public void testAttributeReferencesWithWhiteSpace() { final Map attrs = new HashMap<>(); attrs.put("a b c,d", "abc"); - + final String query = "${ 'a b c,d':equals('abc') }"; verifyEquals(query, attrs, true); } @@ -609,68 +591,68 @@ public class TestQuery { final Map attributes = new HashMap<>(); attributes.put("abc", "xyz"); - final String expression = - "# hello, world\n" + - "${# ref attr\n" + - "\t" + - "abc" + - "\t" + - "#end ref attr\n" + - "}"; + final String expression + = "# hello, world\n" + + "${# ref attr\n" + + "\t" + + "abc" + + "\t" + + "#end ref attr\n" + + "}"; Query query = Query.compile(expression); QueryResult result = query.evaluate(attributes); assertEquals(ResultType.STRING, result.getResultType()); assertEquals("xyz", result.getValue()); - + query = Query.compile("${abc:append('# hello') #good-bye \n}"); result = query.evaluate(attributes); assertEquals(ResultType.STRING, result.getResultType()); assertEquals("xyz# hello", result.getValue()); } - + @Test public void testAppendPrepend() { final Map attributes = new HashMap<>(); attributes.put("attr", "XX"); attributes.put("YXXX", "bingo"); - + verifyEquals("${${attr:append('X'):prepend('Y')}}", attributes, "bingo"); } - + @Test public void testIsNull() { final Map attributes = new HashMap<>(); verifyEquals("${attr:isNull()}", attributes, true); } - + @Test public void testNotNull() { final Map attributes = new HashMap<>(); attributes.put("attr", ""); - + verifyEquals("${attr:notNull()}", attributes, true); } - + @Test public void testIsNullOrLengthEquals0() { final Map attributes = new HashMap<>(); attributes.put("abc", ""); attributes.put("xyz", "xyz"); attributes.put("xx", " "); - + verifyEquals("${abc:isNull():or( ${abc:length():equals(0)} )}", attributes, true); verifyEquals("${xyz:isNull():or( ${xyz:length():equals(0)} )}", attributes, false); verifyEquals("${none:isNull():or( ${none:length():equals(0)} )}", attributes, true); verifyEquals("${xx:isNull():or( ${xx:trim():length():equals(0)} )}", attributes, true); } - + @Test public void testReplaceNull() { final Map attributes = new HashMap<>(); verifyEquals("${attr:replaceNull('hello')}", attributes, "hello"); } - + @Test public void testReplace() { final Map attributes = new HashMap<>(); @@ -683,10 +665,10 @@ public class TestQuery { final Map attributes = new HashMap<>(); attributes.put("attr", "hello"); attributes.put("xyz", "00-00TEST.2014_01_01_000000_value"); - + verifyEquals("${xyz:replaceAll(\"^([^.]+)\\.([0-9]{4})_([0-9]{2})_([0-9]{2}).*$\", \"$3\")}", attributes, "01"); verifyEquals("${attr:replaceAll('l+', 'r')}", attributes, "hero"); - + attributes.clear(); attributes.put("filename1", "abc.gz"); attributes.put("filename2", "abc.g"); @@ -705,10 +687,9 @@ public class TestQuery { verifyEquals("${abc:replaceAll( 'xx', '$0')}", attributes, "hello world"); verifyEquals("${abc:replaceAll( '(xx)', '$1')}", attributes, "hello world"); verifyEquals("${abc:replaceAll( 'lo wor(ld)', '$1')}", attributes, "helld"); - + } - - + @Test public void testReplaceAllWithOddNumberOfBackslashPairs() { final Map attributes = new HashMap<>(); @@ -718,15 +699,15 @@ public class TestQuery { verifyEquals("${filename:replaceAll('\\\\\\\\', '/')}", attributes, "C:/temp/.txt"); verifyEquals("${filename:replaceAll('\\\\\\.txt$', '')}", attributes, "C:\\temp"); } - + @Test public void testReplaceAllWithMatchingGroup() { final Map attributes = new HashMap<>(); attributes.put("attr", "hello"); - + verifyEquals("${attr:replaceAll('.*?(l+).*', '$1')}", attributes, "ll"); } - + @Test public void testMathOperations() { final Map attributes = new HashMap<>(); @@ -746,16 +727,16 @@ public class TestQuery { attributes.put("attr", "https://abc.go"); verifyEquals("${attr:indexOf('/')}", attributes, 6L); } - + @Test public void testDate() { final Calendar now = Calendar.getInstance(); final int year = now.get(Calendar.YEAR); final Map attributes = new HashMap<>(); attributes.put("entryDate", String.valueOf(now.getTimeInMillis())); - + verifyEquals("${entryDate:toNumber():toDate():format('yyyy')}", attributes, String.valueOf(year)); - + attributes.clear(); attributes.put("month", "3"); attributes.put("day", "4"); @@ -765,34 +746,34 @@ public class TestQuery { verifyEquals("${year:append('/'):append(${month}):append('/'):append(${day}):toDate('yyyy/MM/dd'):format('D')}", attributes, "63"); } - + @Test public void testSystemProperty() { System.setProperty("hello", "good-bye"); assertEquals("good-bye", Query.evaluateExpressions("${hello}")); assertEquals("good-bye", Query.compile("${hello}").evaluate().getValue()); } - + @Test public void testAnyAttribute() { final Map attributes = new HashMap<>(); attributes.put("abc", "zzz"); attributes.put("xyz", "abc"); - + verifyEquals("${anyAttribute('abc', 'xyz', 'missingAttr'):substring(1,2):equals('b')}", attributes, true); verifyEquals("${anyAttribute('abc', 'xyz'):substring(1,2):equals('b')}", attributes, true); verifyEquals("${anyAttribute('xyz', 'abc'):substring(1,2):equals('b')}", attributes, true); verifyEquals("${anyAttribute('zz'):substring(1,2):equals('b')}", attributes, false); verifyEquals("${anyAttribute('abc', 'zz'):isNull()}", attributes, true); } - + @Test public void testAnyMatchingAttribute() { final Map attributes = new HashMap<>(); attributes.put("abc", "zzz"); attributes.put("xyz", "abc"); attributes.put("123.cba", "hello"); - + verifyEquals("${anyMatchingAttribute('.{2}x', '.{2}z'):substring(1,2):equals('b')}", attributes, true); verifyEquals("${anyMatchingAttribute('.*'):substring(1,2):equals('b')}", attributes, true); verifyEquals("${anyMatchingAttribute('x{44}'):substring(1,2):equals('b')}", attributes, false); @@ -804,48 +785,46 @@ public class TestQuery { verifyEquals("${anyMatchingAttribute('123\\.c.*'):matches('hello')}", attributes, true); verifyEquals("${anyMatchingAttribute('123\\.c.*|a.c'):matches('zzz')}", attributes, true); } - - + @Test public void testAnyDelineatedValue() { final Map attributes = new HashMap<>(); attributes.put("abc", "a,b,c"); attributes.put("xyz", "abc"); - + final String query = "${anyDelineatedValue('${abc}', ','):equals('b')}"; assertEquals(ResultType.BOOLEAN, Query.getResultType(query)); - + assertEquals("true", Query.evaluateExpressions(query, attributes, null)); assertEquals("true", Query.evaluateExpressions("${anyDelineatedValue('${abc}', ','):equals('a')}", attributes, null)); assertEquals("true", Query.evaluateExpressions("${anyDelineatedValue('${abc}', ','):equals('c')}", attributes, null)); assertEquals("false", Query.evaluateExpressions("${anyDelineatedValue('${abc}', ','):equals('d')}", attributes, null)); - + verifyEquals("${anyDelineatedValue(${abc}, ','):equals('b')}", attributes, true); verifyEquals("${anyDelineatedValue(${abc}, ','):equals('a')}", attributes, true); verifyEquals("${anyDelineatedValue(${abc}, ','):equals('c')}", attributes, true); verifyEquals("${anyDelineatedValue(${abc}, ','):equals('d')}", attributes, false); } - + @Test public void testAllDelineatedValues() { final Map attributes = new HashMap<>(); attributes.put("abc", "a,b,c"); attributes.put("xyz", "abc"); - + final String query = "${allDelineatedValues('${abc}', ','):matches('[abc]')}"; - + assertEquals(ResultType.BOOLEAN, Query.getResultType(query)); assertEquals("true", Query.evaluateExpressions(query, attributes, null)); assertEquals("true", Query.evaluateExpressions(query, attributes, null)); assertEquals("false", Query.evaluateExpressions("${allDelineatedValues('${abc}', ','):matches('[abd]')}", attributes, null)); assertEquals("false", Query.evaluateExpressions("${allDelineatedValues('${abc}', ','):equals('a'):not()}", attributes, null)); - + verifyEquals("${allDelineatedValues(${abc}, ','):matches('[abc]')}", attributes, true); verifyEquals("${allDelineatedValues(${abc}, ','):matches('[abd]')}", attributes, false); verifyEquals("${allDelineatedValues(${abc}, ','):equals('a'):not()}", attributes, false); } - - + @Test public void testAllAttributes() { final Map attributes = new HashMap<>(); @@ -859,7 +838,7 @@ public class TestQuery { verifyEquals("${allAttributes('abc', 'hello'):length():equals(4)}", attributes, false); verifyEquals("${allAttributes('abc', 'xyz'):length():equals(4)}", attributes, true); verifyEquals("${allAttributes('abc', 'xyz', 'other'):isNull()}", attributes, false); - + try { Query.compile("${allAttributes('#ah'):equals('hello')"); Assert.fail("Was able to compile with allAttributes and an invalid attribute name"); @@ -867,8 +846,7 @@ public class TestQuery { // expected behavior } } - - + @Test public void testMathOperators() { final Map attributes = new HashMap<>(); @@ -878,7 +856,7 @@ public class TestQuery { verifyEquals("${xyz:toNumber():gt( ${abc:toNumber()} )}", attributes, true); } - + @Test public void testAllMatchingAttributes() { final Map attributes = new HashMap<>(); @@ -887,17 +865,17 @@ public class TestQuery { attributes.put("hello", "world!"); attributes.put("123.cba", "hell.o"); - System.out.println( printTree(Query.compile("${allMatchingAttributes('(abc|xyz)'):matches('\\\\d+')}").getTree()) ); - + System.out.println(printTree(Query.compile("${allMatchingAttributes('(abc|xyz)'):matches('\\\\d+')}").getTree())); + verifyEquals("${'123.cba':matches('hell\\.o')}", attributes, true); verifyEquals("${allMatchingAttributes('123\\.cba'):equals('hell.o')}", attributes, true); verifyEquals("${allMatchingAttributes('(abc|xyz)'):matches('\\d+')}", attributes, true); verifyEquals("${allMatchingAttributes('[ax].*'):toNumber():lt(99999)}", attributes, true); verifyEquals("${allMatchingAttributes('hell.'):length():gt(3)}", attributes, true); - + verifyEquals("${allMatchingAttributes('123\\.cba'):equals('no')}", attributes, false); } - + @Test public void testMatches() { final Map attributes = new HashMap<>(); @@ -909,15 +887,14 @@ public class TestQuery { final String evaluated = Query.evaluateExpressions("${abc:matches('1234${end}4321')}", attributes, null); assertEquals("true", evaluated); - + attributes.put("end", "888"); final String secondEvaluation = Query.evaluateExpressions("${abc:matches('1234${end}4321')}", attributes, null); assertEquals("false", secondEvaluation); - + verifyEquals("${dotted:matches('abc\\.xyz')}", attributes, true); - } - - + } + @Test public void testFind() { final Map attributes = new HashMap<>(); @@ -929,68 +906,67 @@ public class TestQuery { final String evaluated = Query.evaluateExpressions("${abc:find('1234${end}4321')}", attributes, null); assertEquals("true", evaluated); - + attributes.put("end", "888"); final String secondEvaluation = Query.evaluateExpressions("${abc:find('${end}4321')}", attributes, null); assertEquals("false", secondEvaluation); - + verifyEquals("${dotted:find('\\.')}", attributes, true); - } - + } + @Test public void testSubstringAfter() { final Map attributes = new HashMap<>(); attributes.put("filename", "file-255"); - + verifyEquals("${filename:substringAfter('')}", attributes, "file-255"); verifyEquals("${filename:substringAfterLast('')}", attributes, "file-255"); verifyEquals("${filename:substringBefore('')}", attributes, "file-255"); verifyEquals("${filename:substringBeforeLast('')}", attributes, "file-255"); verifyEquals("${filename:substringBefore('file')}", attributes, ""); - + attributes.put("uri", "sftp://some.uri"); verifyEquals("${uri:substringAfter('sftp')}", attributes, "://some.uri"); } - + @Test public void testSubstringAfterLast() { final Map attributes = new HashMap<>(); attributes.put("filename", "file-file-255"); - + verifyEquals("${filename:substringAfterLast('file-')}", attributes, "255"); verifyEquals("${filename:substringAfterLast('5')}", attributes, ""); verifyEquals("${filename:substringAfterLast('x')}", attributes, "file-file-255"); } - + @Test public void testSubstringBefore() { final Map attributes = new HashMap<>(); attributes.put("something", "some {} or other"); - + verifyEquals("${something:substringBefore('}')}", attributes, "some {"); } - + @Test public void testSubstring() { final Map attributes = new HashMap<>(); attributes.put("filename", "file-255"); - + verifyEquals("${filename:substring(1, 2)}", attributes, "i"); verifyEquals("${filename:substring(4)}", attributes, "-255"); } - + @Test public void testToRadix() { final Map attributes = new HashMap<>(); attributes.put("filename", "file-255"); attributes.put("filename2", "file-99999"); - verifyEquals("${filename:substringAfter('-'):toNumber():toRadix(16):toUpper()}", attributes, "FF"); verifyEquals("${filename:substringAfter('-'):toNumber():toRadix(16, 4):toUpper()}", attributes, "00FF"); verifyEquals("${filename:substringAfter('-'):toNumber():toRadix(36, 3):toUpper()}", attributes, "073"); } - + @Test public void testDateFormatConversion() { final Map attributes = new HashMap<>(); @@ -998,23 +974,22 @@ public class TestQuery { verifyEquals("${blue:toDate('yyyyMMddHHmmss'):format(\"yyyy/MM/dd HH:mm:ss.SSS'Z'\")}", attributes, "2013/09/17 16:26:43.000Z"); } - @Test public void testNot() { verifyEquals("${ab:notNull():not()}", new HashMap(), true); } - + @Test public void testAttributesWithSpaces() { final Map attributes = new HashMap<>(); attributes.put("ab", "abc"); attributes.put("a b", "abc"); - + verifyEquals("${ab}", attributes, "abc"); verifyEquals("${'a b'}", attributes, "abc"); verifyEquals("${'a b':replaceNull('')}", attributes, ""); } - + @Test public void testOr() { final Map attributes = new HashMap<>(); @@ -1029,7 +1004,7 @@ public class TestQuery { verifyEquals("${filename1:startsWith('x'):or( ${filename2:startsWith('y')} )}", attributes, true); verifyEquals("${filename2:startsWith('x'):or( ${filename1:startsWith('y')} )}", attributes, false); } - + @Test public void testAnd() { final Map attributes = new HashMap<>(); @@ -1046,7 +1021,7 @@ public class TestQuery { verifyEquals("${filename2:startsWith('x'):and( ${filename1:startsWith('y')} )}", attributes, false); verifyEquals("${filename1:startsWith('x'):and( ${'filename 3':endsWith('y')} )}", attributes, true); } - + @Test public void testAndOrNot() { final Map attributes = new HashMap<>(); @@ -1054,90 +1029,90 @@ public class TestQuery { attributes.put("filename2", "yabc"); attributes.put("filename 3", "abcxy"); - final String query = - "${" + - " 'non-existing':notNull():not():and(" + // true AND ( - " ${filename1:startsWith('y')" + // false - " :or(" + // or - " ${ filename1:startsWith('x'):and(false) }" + // false - " ):or(" + // or - " ${ filename2:endsWith('xxxx'):or( ${'filename 3':length():gt(1)} ) }" + // true ) - " )}" + - " )" + - "}"; - + final String query + = "${" + + " 'non-existing':notNull():not():and(" + // true AND ( + " ${filename1:startsWith('y')" + // false + " :or(" + // or + " ${ filename1:startsWith('x'):and(false) }" + // false + " ):or(" + // or + " ${ filename2:endsWith('xxxx'):or( ${'filename 3':length():gt(1)} ) }" + // true ) + " )}" + + " )" + + "}"; + System.out.println(query); verifyEquals(query, attributes, true); } - + @Test public void testAndOrLogicWithAnyAll() { final Map attributes = new HashMap<>(); attributes.put("filename1", "xabc"); attributes.put("filename2", "yabc"); attributes.put("filename 3", "abcxy"); - + verifyEquals("${anyMatchingAttribute('filename.*'):contains('abc'):and( ${filename2:equals('yabc')} )}", attributes, true); verifyEquals("${anyMatchingAttribute('filename.*'):contains('abc'):and( ${filename2:equals('xabc')} )}", attributes, false); verifyEquals("${anyMatchingAttribute('filename.*'):contains('abc'):not():or( ${filename2:equals('yabc')} )}", attributes, true); verifyEquals("${anyMatchingAttribute('filename.*'):contains('abc'):not():or( ${filename2:equals('xabc')} )}", attributes, false); } - + @Test public void testKeywords() { final Map attributes = new HashMap<>(); attributes.put("UUID", "123"); verifyEquals("${ 'UUID':toNumber():equals(123) }", attributes, true); } - + @Test public void testEqualsNumber() { final Map attributes = new HashMap<>(); attributes.put("abc", "123"); verifyEquals("${ abc:toNumber():equals(123) }", attributes, true); } - + @Test public void testSubjectAsEmbeddedExpressionWithSurroundChars() { final Map attributes = new HashMap<>(); attributes.put("b", "x"); attributes.put("abcxcba", "hello"); - + final String evaluated = Query.evaluateExpressions("${ 'abc${b}cba':substring(0, 1) }", attributes, null); assertEquals("h", evaluated); } - + @Test public void testToNumberFunctionReturnsNumberType() { assertEquals(ResultType.NUMBER, Query.getResultType("${header.size:toNumber()}")); } - + @Test public void testAnyAttributeEmbedded() { final Map attributes = new HashMap<>(); attributes.put("a1", "test1"); attributes.put("b2", "2test"); attributes.put("c3", "3test3"); - + final String query = "${a1:equals('test1'):and( ${anyAttribute('a1','b2','c3'):contains('2')})}"; verifyEquals(query, attributes, true); } - + private void verifyEquals(final String expression, final Map 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); - - if ( expectedResult instanceof Number ) { + + if (expectedResult instanceof Number) { assertEquals(ResultType.NUMBER, result.getResultType()); - } else if ( expectedResult instanceof Boolean ) { + } else if (expectedResult instanceof Boolean) { assertEquals(ResultType.BOOLEAN, result.getResultType()); } else { assertEquals(ResultType.STRING, result.getResultType()); } - + assertEquals(expectedResult, result.getValue()); } } diff --git a/nifi/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestStandardPreparedQuery.java b/nifi/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestStandardPreparedQuery.java index 398a23b640..5acba8deda 100644 --- a/nifi/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestStandardPreparedQuery.java +++ b/nifi/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestStandardPreparedQuery.java @@ -31,34 +31,34 @@ public class TestStandardPreparedQuery { public void testSimpleReference() { final Map attrs = new HashMap<>(); attrs.put("xx", "world"); - + assertEquals("world", evaluate("${xx}", attrs)); assertEquals("hello, world!", evaluate("hello, ${xx}!", attrs)); } - + @Test public void testEmbeddedReference() { final Map attrs = new HashMap<>(); attrs.put("xx", "yy"); attrs.put("yy", "world"); - + assertEquals("world", evaluate("${${xx}}", attrs)); } - + @Test public void test10MIterations() { final Map attrs = new HashMap<>(); attrs.put("xx", "world"); - + final StandardPreparedQuery prepared = (StandardPreparedQuery) Query.prepare("${xx}"); final long start = System.nanoTime(); - for (int i=0; i < 10000000; i++) { - assertEquals( "world", prepared.evaluateExpressions(attrs, null) ); + for (int i = 0; i < 10000000; i++) { + assertEquals("world", prepared.evaluateExpressions(attrs, null)); } final long nanos = System.nanoTime() - start; System.out.println(TimeUnit.NANOSECONDS.toMillis(nanos)); } - + @Test @Ignore("Takes too long") public void test10MIterationsWithQuery() { @@ -66,14 +66,14 @@ public class TestStandardPreparedQuery { attrs.put("xx", "world"); final long start = System.nanoTime(); - for (int i=0; i < 10000000; i++) { - assertEquals( "world", Query.evaluateExpressions("${xx}", attrs) ); + for (int i = 0; i < 10000000; i++) { + assertEquals("world", Query.evaluateExpressions("${xx}", attrs)); } final long nanos = System.nanoTime() - start; System.out.println(TimeUnit.NANOSECONDS.toMillis(nanos)); } - + @Test public void testSeveralSequentialExpressions() { final Map attributes = new HashMap<>(); @@ -83,10 +83,10 @@ public class TestStandardPreparedQuery { assertEquals("Hello, World, how are you?!", evaluate("Hello, ${audience}${comma}${question}!", attributes)); } - + private String evaluate(final String query, final Map attrs) { final String evaluated = ((StandardPreparedQuery) Query.prepare(query)).evaluateExpressions(attrs, null); return evaluated; } - + }