added functions for escaping text to the expression language

Signed-off-by: Matt Burgess <mattyb149@apache.org>
This commit is contained in:
devin fisher 2016-07-28 05:17:39 +02:00 committed by Matt Burgess
parent 6f85440ebd
commit 8f74241a10
6 changed files with 131 additions and 51 deletions

View File

@ -118,6 +118,15 @@ NOT : 'not';
COUNT : 'count'; COUNT : 'count';
RANDOM : 'random'; RANDOM : 'random';
ESCAPE_JSON : 'escapeJson'; ESCAPE_JSON : 'escapeJson';
ESCAPE_XML : 'escapeXml';
ESCAPE_CSV : 'escapeCsv';
ESCAPE_HTML3 : 'escapeHtml3';
ESCAPE_HTML4 : 'escapeHtml4';
UNESCAPE_JSON : 'unescapeJson';
UNESCAPE_XML : 'unescapeXml';
UNESCAPE_CSV : 'unescapeCsv';
UNESCAPE_HTML3 : 'unescapeHtml3';
UNESCAPE_HTML4 : 'unescapeHtml4';
// 1 arg functions // 1 arg functions
SUBSTRING_AFTER : 'substringAfter'; SUBSTRING_AFTER : 'substringAfter';

View File

@ -73,7 +73,7 @@ tokens {
} }
// functions that return Strings // functions that return Strings
zeroArgString : (TO_UPPER | TO_LOWER | TRIM | TO_STRING | URL_ENCODE | URL_DECODE | ESCAPE_JSON) LPAREN! RPAREN!; zeroArgString : (TO_UPPER | TO_LOWER | TRIM | TO_STRING | URL_ENCODE | URL_DECODE | ESCAPE_JSON | ESCAPE_XML | ESCAPE_CSV | ESCAPE_HTML3 | ESCAPE_HTML4 | UNESCAPE_JSON | UNESCAPE_XML | UNESCAPE_CSV | UNESCAPE_HTML3 | UNESCAPE_HTML4 ) LPAREN! RPAREN!;
oneArgString : ((SUBSTRING_BEFORE | SUBSTRING_BEFORE_LAST | SUBSTRING_AFTER | SUBSTRING_AFTER_LAST | REPLACE_NULL | REPLACE_EMPTY | oneArgString : ((SUBSTRING_BEFORE | SUBSTRING_BEFORE_LAST | SUBSTRING_AFTER | SUBSTRING_AFTER_LAST | REPLACE_NULL | REPLACE_EMPTY |
PREPEND | APPEND | FORMAT | STARTS_WITH | ENDS_WITH | CONTAINS | JOIN | JSON_PATH) LPAREN! anyArg RPAREN!) | PREPEND | APPEND | FORMAT | STARTS_WITH | ENDS_WITH | CONTAINS | JOIN | JSON_PATH) LPAREN! anyArg RPAREN!) |
(TO_RADIX LPAREN! anyArg (COMMA! anyArg)? RPAREN!); (TO_RADIX LPAREN! anyArg (COMMA! anyArg)? RPAREN!);

View File

@ -44,6 +44,7 @@ import org.apache.nifi.attribute.expression.language.evaluation.functions.Divide
import org.apache.nifi.attribute.expression.language.evaluation.functions.EndsWithEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.EndsWithEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.EqualsEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.EqualsEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.EqualsIgnoreCaseEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.EqualsIgnoreCaseEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.CharSequenceTranslatorEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.FindEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.FindEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.FormatEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.FormatEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.GetDelimitedFieldEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.GetDelimitedFieldEvaluator;
@ -93,7 +94,6 @@ import org.apache.nifi.attribute.expression.language.evaluation.functions.ToUppe
import org.apache.nifi.attribute.expression.language.evaluation.functions.TrimEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.TrimEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.UrlDecodeEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.UrlDecodeEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.UrlEncodeEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.UrlEncodeEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.EscapeJsonEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.UuidEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.UuidEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.literals.BooleanLiteralEvaluator; 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.NumberLiteralEvaluator;
@ -193,6 +193,15 @@ 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_DECODE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.URL_ENCODE; import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.URL_ENCODE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_JSON; import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_JSON;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_CSV;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_HTML3;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_HTML4;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_XML;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UNESCAPE_JSON;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UNESCAPE_CSV;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UNESCAPE_HTML3;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UNESCAPE_HTML4;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UNESCAPE_XML;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UUID; import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UUID;
import org.apache.nifi.attribute.expression.language.evaluation.selection.MappingEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.selection.MappingEvaluator;
@ -924,9 +933,45 @@ public class Query {
verifyArgCount(argEvaluators, 0, "urlDecode"); verifyArgCount(argEvaluators, 0, "urlDecode");
return addToken(new UrlDecodeEvaluator(toStringEvaluator(subjectEvaluator)), "urlDecode"); return addToken(new UrlDecodeEvaluator(toStringEvaluator(subjectEvaluator)), "urlDecode");
} }
case ESCAPE_CSV: {
verifyArgCount(argEvaluators, 0, "escapeCsv");
return addToken(CharSequenceTranslatorEvaluator.csvEscapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
}
case ESCAPE_HTML3: {
verifyArgCount(argEvaluators, 0, "escapeHtml3");
return addToken(CharSequenceTranslatorEvaluator.html3EscapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
}
case ESCAPE_HTML4: {
verifyArgCount(argEvaluators, 0, "escapeHtml4");
return addToken(CharSequenceTranslatorEvaluator.html4EscapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
}
case ESCAPE_JSON: { case ESCAPE_JSON: {
verifyArgCount(argEvaluators, 0, "escapeJson"); verifyArgCount(argEvaluators, 0, "escapeJson");
return addToken(new EscapeJsonEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson"); return addToken(CharSequenceTranslatorEvaluator.jsonEscapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
}
case ESCAPE_XML: {
verifyArgCount(argEvaluators, 0, "escapeXml");
return addToken(CharSequenceTranslatorEvaluator.xmlEscapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
}
case UNESCAPE_CSV: {
verifyArgCount(argEvaluators, 0, "unescapeCsv");
return addToken(CharSequenceTranslatorEvaluator.csvUnescapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
}
case UNESCAPE_HTML3: {
verifyArgCount(argEvaluators, 0, "unescapeHtml3");
return addToken(CharSequenceTranslatorEvaluator.html3UnescapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
}
case UNESCAPE_HTML4: {
verifyArgCount(argEvaluators, 0, "unescapeHtml4");
return addToken(CharSequenceTranslatorEvaluator.html4UnescapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
}
case UNESCAPE_JSON: {
verifyArgCount(argEvaluators, 0, "unescapeJson");
return addToken(CharSequenceTranslatorEvaluator.jsonUnescapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
}
case UNESCAPE_XML: {
verifyArgCount(argEvaluators, 0, "unescapeXml");
return addToken(CharSequenceTranslatorEvaluator.xmlUnescapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
} }
case SUBSTRING_BEFORE: { case SUBSTRING_BEFORE: {
verifyArgCount(argEvaluators, 1, "substringBefore"); verifyArgCount(argEvaluators, 1, "substringBefore");

View File

@ -0,0 +1,73 @@
package org.apache.nifi.attribute.expression.language.evaluation.functions;
import java.util.Map;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.text.translate.CharSequenceTranslator;
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 CharSequenceTranslatorEvaluator extends StringEvaluator
{
public static StringEvaluator jsonEscapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.ESCAPE_JSON);
}
public static StringEvaluator xmlEscapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.ESCAPE_XML10);
}
public static StringEvaluator csvEscapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.ESCAPE_CSV);
}
public static StringEvaluator html3EscapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.ESCAPE_HTML3);
}
public static StringEvaluator html4EscapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.ESCAPE_HTML4);
}
public static StringEvaluator jsonUnescapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.UNESCAPE_JSON);
}
public static StringEvaluator xmlUnescapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.UNESCAPE_XML);
}
public static StringEvaluator csvUnescapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.UNESCAPE_CSV);
}
public static StringEvaluator html3UnescapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.UNESCAPE_HTML3);
}
public static StringEvaluator html4UnescapeEvaluator(final Evaluator<String> subject){
return new CharSequenceTranslatorEvaluator(subject, StringEscapeUtils.UNESCAPE_HTML4);
}
private final Evaluator<String> subject;
private final CharSequenceTranslator method;
public CharSequenceTranslatorEvaluator(final Evaluator<String> subject, CharSequenceTranslator method) {
this.subject = subject;
this.method = method;
}
@Override
public QueryResult<String> evaluate(final Map<String, String> attributes) {
final String subjectValue = subject.evaluate(attributes).getValue();
return new StringQueryResult(subjectValue == null ? "" : method.translate(subjectValue));
}
@Override
public Evaluator<?> getSubjectEvaluator() {
return subject;
}
}

View File

@ -1,47 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.attribute.expression.language.evaluation.functions;
import 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;
import org.apache.commons.lang3.StringEscapeUtils;
public class EscapeJsonEvaluator extends StringEvaluator {
private final Evaluator<String> subject;
public EscapeJsonEvaluator(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 ? "" : StringEscapeUtils.escapeJson(subjectValue));
}
@Override
public Evaluator<?> getSubjectEvaluator() {
return subject;
}
}

View File

@ -1315,7 +1315,7 @@ public class TestQuery {
} }
@Test @Test
public void testEscapeJson() { public void testEscapeFunctions() {
final Map<String, String> attributes = new HashMap<>(); final Map<String, String> attributes = new HashMap<>();
attributes.put("string", "making air \"QUOTES\"."); attributes.put("string", "making air \"QUOTES\".");