EscapeJson function added to expression-language

Made use of org.apache.commons.lang3.StringEscapeUtils to do that
actual processing

Signed-off-by: Matt Burgess <mattyb149@apache.org>
This commit is contained in:
Devin Fisher 2016-07-03 01:53:16 +02:00 committed by Matt Burgess
parent e5e86cf07c
commit ebd11b1d8f
5 changed files with 75 additions and 13 deletions

View File

@ -41,7 +41,7 @@ lexer grammar AttributeExpressionLexer;
}
sb.append(", column ").append(e.charPositionInLine);
sb.append(". Query: ").append(e.input.toString());
throw new AttributeExpressionLanguageParsingException(sb.toString());
}
@ -58,9 +58,9 @@ lexer grammar AttributeExpressionLexer;
}
sb.append(", column ").append(e.charPositionInLine);
sb.append(". Query: ").append(e.input.toString());
throw new AttributeExpressionLanguageParsingException(sb.toString());
}
}
}
@ -117,6 +117,7 @@ URL_DECODE : 'urlDecode';
NOT : 'not';
COUNT : 'count';
RANDOM : 'random';
ESCAPE_JSON : 'escapeJson';
// 1 arg functions
SUBSTRING_AFTER : 'substringAfter';
@ -174,7 +175,7 @@ STRING_LITERAL
'"'
(
escaped=ESC {lBuf.append(getText());} |
normal = ~( '"' | '\\' | '\n' | '\r' | '\t' ) { lBuf.appendCodePoint(normal);}
normal = ~( '"' | '\\' | '\n' | '\r' | '\t' ) { lBuf.appendCodePoint(normal);}
)*
'"'
)
@ -186,7 +187,7 @@ STRING_LITERAL
'\''
(
escaped=ESC {lBuf.append(getText());} |
normal = ~( '\'' | '\\' | '\n' | '\r' | '\t' ) { lBuf.appendCodePoint(normal);}
normal = ~( '\'' | '\\' | '\n' | '\r' | '\t' ) { lBuf.appendCodePoint(normal);}
)*
'\''
)
@ -206,7 +207,7 @@ ESC
| 'n' { setText("\n"); }
| 't' { setText("\t"); }
| '\\' { setText("\\\\"); }
| nextChar = ~('"' | '\'' | 'r' | 'n' | 't' | '\\')
| nextChar = ~('"' | '\'' | 'r' | 'n' | 't' | '\\')
{
StringBuilder lBuf = new StringBuilder(); lBuf.append("\\\\").appendCodePoint(nextChar); setText(lBuf.toString());
}

View File

@ -50,7 +50,7 @@ tokens {
}
sb.append(", column ").append(e.charPositionInLine);
sb.append(". Query: ").append(e.input.toString());
throw new AttributeExpressionLanguageParsingException(sb.toString());
}
@ -67,13 +67,13 @@ tokens {
}
sb.append(", column ").append(e.charPositionInLine);
sb.append(". Query: ").append(e.input.toString());
throw new AttributeExpressionLanguageParsingException(sb.toString());
}
}
}
// functions that return Strings
zeroArgString : (TO_UPPER | TO_LOWER | TRIM | TO_STRING | URL_ENCODE | URL_DECODE) LPAREN! RPAREN!;
zeroArgString : (TO_UPPER | TO_LOWER | TRIM | TO_STRING | URL_ENCODE | URL_DECODE | ESCAPE_JSON) LPAREN! RPAREN!;
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!) |
(TO_RADIX LPAREN! anyArg (COMMA! anyArg)? RPAREN!);
@ -113,7 +113,7 @@ attrName : singleAttrName | multiAttrName;
singleAttrRef : ATTRIBUTE_NAME | STRING_LITERAL;
singleAttrName : singleAttrRef ->
^(ATTR_NAME singleAttrRef);
multiAttrFunction : ANY_ATTRIBUTE | ANY_MATCHING_ATTRIBUTE | ALL_ATTRIBUTES | ALL_MATCHING_ATTRIBUTES | ANY_DELINEATED_VALUE | ALL_DELINEATED_VALUES;
multiAttrName : multiAttrFunction LPAREN stringArg (COMMA stringArg)* RPAREN ->
@ -121,14 +121,14 @@ multiAttrName : multiAttrFunction LPAREN stringArg (COMMA stringArg)* RPAREN ->
attributeRef : subject ->
^(ATTRIBUTE_REFERENCE subject);
functionCall : functionRef ->
^(FUNCTION_CALL functionRef);
booleanLiteral : TRUE | FALSE;
zeroArgStandaloneFunction : (IP | UUID | NOW | NEXT_INT | HOSTNAME | RANDOM) LPAREN! RPAREN!;
oneArgStandaloneFunction : (TO_LITERAL^ LPAREN! anyArg RPAREN!) |
oneArgStandaloneFunction : (TO_LITERAL^ LPAREN! anyArg RPAREN!) |
(HOSTNAME^ LPAREN! booleanLiteral RPAREN!);
standaloneFunction : zeroArgStandaloneFunction | oneArgStandaloneFunction;

View File

@ -93,6 +93,7 @@ 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.UrlDecodeEvaluator;
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.literals.BooleanLiteralEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.literals.NumberLiteralEvaluator;
@ -191,6 +192,7 @@ import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpre
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.ESCAPE_JSON;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UUID;
import org.apache.nifi.attribute.expression.language.evaluation.selection.MappingEvaluator;
@ -922,6 +924,10 @@ public class Query {
verifyArgCount(argEvaluators, 0, "urlDecode");
return addToken(new UrlDecodeEvaluator(toStringEvaluator(subjectEvaluator)), "urlDecode");
}
case ESCAPE_JSON: {
verifyArgCount(argEvaluators, 0, "escapeJson");
return addToken(new EscapeJsonEvaluator(toStringEvaluator(subjectEvaluator)), "urlDecode");
}
case SUBSTRING_BEFORE: {
verifyArgCount(argEvaluators, 1, "substringBefore");
return addToken(new SubstringBeforeEvaluator(toStringEvaluator(subjectEvaluator),

View File

@ -0,0 +1,47 @@
/*
* 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

@ -1314,6 +1314,14 @@ public class TestQuery {
verifyEquals("${line:getDelimitedField(2)}", attributes, " 32");
}
@Test
public void testEscapeJson() {
final Map<String, String> attributes = new HashMap<>();
attributes.put("string", "making air \"QUOTES\".");
verifyEquals("${string:escapeJson()}", attributes, "making air \\\"QUOTES\\\".");
}
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));