mirror of https://github.com/apache/nifi.git
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:
parent
e5e86cf07c
commit
ebd11b1d8f
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue