use of org.apache.nifi.record.path.exception.RecordPathException in project nifi by apache.
the class RecordPath method compile.
/**
* Compiles a RecordPath from the given text
*
* @param path the textual representation of the RecordPath
* @return the compiled RecordPath
* @throws RecordPathException if the given text is not a valid RecordPath
*/
public static RecordPath compile(final String path) throws RecordPathException {
try {
final CharStream input = new ANTLRStringStream(path);
final RecordPathLexer lexer = new RecordPathLexer(input);
final CommonTokenStream lexerTokenStream = new CommonTokenStream(lexer);
final RecordPathParser parser = new RecordPathParser(lexerTokenStream);
final Tree tree = (Tree) parser.pathExpression().getTree();
// We look at the first child, because 'tree' is a PATH_EXPRESSION and we really
// want the underlying PATH token.
final Tree firstChild = tree.getChild(0);
final int childType = firstChild.getType();
final boolean absolute;
final RecordPathSegment rootPath;
if (childType == PATH || childType == CHILD_REFERENCE) {
rootPath = new RootPath();
absolute = true;
} else {
rootPath = null;
absolute = false;
}
return RecordPathCompiler.compile(firstChild, rootPath, absolute);
} catch (final RecordPathException e) {
throw e;
} catch (final Exception e) {
throw new RecordPathException(e);
}
}
use of org.apache.nifi.record.path.exception.RecordPathException in project nifi by apache.
the class RecordPathCompiler method buildPath.
public static RecordPathSegment buildPath(final Tree tree, final RecordPathSegment parent, final boolean absolute) {
switch(tree.getType()) {
case ROOT_REFERENCE:
{
return new RootPath();
}
case CHILD_REFERENCE:
{
final Tree childTree = tree.getChild(0);
final int childTreeType = childTree.getType();
if (childTreeType == FIELD_NAME) {
final String childName = childTree.getChild(0).getText();
return new ChildFieldPath(childName, parent, absolute);
} else if (childTreeType == WILDCARD) {
return new WildcardChildPath(parent, absolute);
} else {
throw new RecordPathException("Expected field name following '/' Token but found " + childTree);
}
}
case ARRAY_INDEX:
{
final Tree indexListTree = tree.getChild(0);
if (indexListTree.getType() == NUMBER_LIST) {
if (indexListTree.getChildCount() == 1 && indexListTree.getChild(0).getType() == NUMBER) {
final Tree indexTree = indexListTree.getChild(0);
final int index = Integer.parseInt(indexTree.getText());
return new ArrayIndexPath(index, parent, absolute);
}
final List<NumericRange> indexList = new ArrayList<>();
for (int i = 0; i < indexListTree.getChildCount(); i++) {
final Tree indexTree = indexListTree.getChild(i);
if (indexTree.getType() == NUMBER) {
final int index = Integer.valueOf(indexTree.getText());
indexList.add(new NumericRange(index, index));
} else if (indexTree.getType() == NUMBER_RANGE) {
final int min = Integer.valueOf(indexTree.getChild(0).getText());
final int max = Integer.valueOf(indexTree.getChild(1).getText());
indexList.add(new NumericRange(min, max));
} else {
throw new RecordPathException("Expected Number or Range following '[' Token but found " + indexTree);
}
}
return new MultiArrayIndexPath(indexList, parent, absolute);
} else {
throw new RecordPathException("Expected Number or Range following '[' Token but found " + indexListTree);
}
}
case MAP_KEY:
{
final Tree keyTree = tree.getChild(0);
if (keyTree.getType() == STRING_LIST) {
if (keyTree.getChildCount() == 1) {
return new SingularMapKeyPath(keyTree.getChild(0).getText(), parent, absolute);
}
final List<String> keys = new ArrayList<>(keyTree.getChildCount());
for (int i = 0; i < keyTree.getChildCount(); i++) {
keys.add(keyTree.getChild(i).getText());
}
return new MultiMapKeyPath(keys, parent, absolute);
} else {
throw new RecordPathException("Expected Map Key following '[' Token but found " + keyTree);
}
}
case WILDCARD:
{
return new WildcardIndexPath(parent, absolute);
}
case DESCENDANT_REFERENCE:
{
final Tree childTree = tree.getChild(0);
final int childTreeType = childTree.getType();
if (childTreeType == FIELD_NAME) {
final String descendantName = childTree.getChild(0).getText();
return new DescendantFieldPath(descendantName, parent, absolute);
} else if (childTreeType == WILDCARD) {
return new WildcardDescendantPath(parent, absolute);
} else {
throw new RecordPathException("Expected field name following '//' Token but found " + childTree);
}
}
case PARENT_REFERENCE:
{
return new ParentPath(parent, absolute);
}
case CURRENT_FIELD:
{
return new CurrentFieldPath(parent, absolute);
}
case STRING_LITERAL:
{
return new LiteralValuePath(parent, tree.getText(), absolute);
}
case NUMBER:
{
return new LiteralValuePath(parent, Integer.parseInt(tree.getText()), absolute);
}
case PREDICATE:
{
final Tree operatorTree = tree.getChild(0);
final RecordPathFilter filter = createFilter(operatorTree, parent, absolute);
return new PredicatePath(parent, filter, absolute);
}
case RELATIVE_PATH:
{
return compile(tree, parent, absolute);
}
case PATH:
{
return compile(tree, new RootPath(), absolute);
}
case FUNCTION:
{
final String functionName = tree.getChild(0).getText();
final Tree argumentListTree = tree.getChild(1);
switch(functionName) {
case "substring":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 3, functionName, absolute);
return new Substring(args[0], args[1], args[2], absolute);
}
case "substringAfter":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new SubstringAfter(args[0], args[1], absolute);
}
case "substringAfterLast":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new SubstringAfterLast(args[0], args[1], absolute);
}
case "substringBefore":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new SubstringBefore(args[0], args[1], absolute);
}
case "substringBeforeLast":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new SubstringBeforeLast(args[0], args[1], absolute);
}
case "replace":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 3, functionName, absolute);
return new Replace(args[0], args[1], args[2], absolute);
}
case "replaceRegex":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 3, functionName, absolute);
return new ReplaceRegex(args[0], args[1], args[2], absolute);
}
case "replaceNull":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new ReplaceNull(args[0], args[1], absolute);
}
case "concat":
{
final int numArgs = argumentListTree.getChildCount();
final RecordPathSegment[] argPaths = new RecordPathSegment[numArgs];
for (int i = 0; i < numArgs; i++) {
argPaths[i] = buildPath(argumentListTree.getChild(i), null, absolute);
}
return new Concat(argPaths, absolute);
}
case "fieldName":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 1, functionName, absolute);
return new FieldName(args[0], absolute);
}
case "toDate":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new ToDate(args[0], args[1], absolute);
}
case "format":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new Format(args[0], args[1], absolute);
}
default:
{
throw new RecordPathException("Invalid function call: The '" + functionName + "' function does not exist or can only " + "be used within a predicate, not as a standalone function");
}
}
}
}
throw new RecordPathException("Encountered unexpected token " + tree);
}
use of org.apache.nifi.record.path.exception.RecordPathException in project nifi by apache.
the class RecordPathCompiler method createFunctionFilter.
private static RecordPathFilter createFunctionFilter(final Tree functionTree, final boolean absolute) {
final String functionName = functionTree.getChild(0).getText();
final Tree argumentListTree = functionTree.getChild(1);
switch(functionName) {
case "contains":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new Contains(args[0], args[1]);
}
case "matchesRegex":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new MatchesRegex(args[0], args[1]);
}
case "containsRegex":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new ContainsRegex(args[0], args[1]);
}
case "startsWith":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new StartsWith(args[0], args[1]);
}
case "endsWith":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 2, functionName, absolute);
return new EndsWith(args[0], args[1]);
}
case "isEmpty":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 1, functionName, absolute);
return new IsEmpty(args[0]);
}
case "isBlank":
{
final RecordPathSegment[] args = getArgPaths(argumentListTree, 1, functionName, absolute);
return new IsBlank(args[0]);
}
case "not":
{
final int numArgs = argumentListTree.getChildCount();
if (numArgs != 1) {
throw new RecordPathException("Invalid number of arguments: " + functionName + " function takes 1 argument but got " + numArgs);
}
final Tree childTree = argumentListTree.getChild(0);
final RecordPathFilter childFilter = createFilter(childTree, null, absolute);
return new NotFilter(childFilter);
}
}
throw new RecordPathException("Invalid function name: " + functionName);
}
Aggregations