Search in sources :

Example 11 with JexlNodes.children

use of org.apache.commons.jexl2.parser.JexlNodes.children in project datawave by NationalSecurityAgency.

the class WhindexVisitor method distributeAndedNodes.

private JexlNode distributeAndedNodes(ASTAndNode node, List<JexlNode> orNodesWithMarkers) {
    // distribute the non-marker nodes into the marker nodes
    List<JexlNode> nodesToDistribute = new ArrayList<>();
    for (JexlNode child : JexlNodes.children(node)) {
        if (!orNodesWithMarkers.contains(child)) {
            nodesToDistribute.add(child);
        }
    }
    List<JexlNode> newOrNodes = new ArrayList<>();
    for (JexlNode orNode : orNodesWithMarkers) {
        List<JexlNode> newOrNodeChildren = new ArrayList<>();
        List<JexlNode> otherOrNodeChildren = new ArrayList<>();
        for (JexlNode orNodeChild : JexlNodes.children(JexlASTHelper.dereference(orNode))) {
            // distribute the nodes when we encounter an EQ node which could be used for field mapping
            if (orNodeChild instanceof ASTEQNode && isFieldValueTerm((ASTEQNode) orNodeChild)) {
                List<JexlNode> newChildren = new ArrayList<>();
                for (JexlNode newChild : nodesToDistribute) {
                    newChildren.add(RebuildingVisitor.copy(newChild));
                }
                newChildren.add(RebuildingVisitor.copy(orNodeChild));
                newOrNodeChildren.add(createUnwrappedAndNode(newChildren));
            } else // group all of the nodes which can't be used for field mapping separately, and handle them below
            {
                otherOrNodeChildren.add(RebuildingVisitor.copy(orNodeChild));
            }
        }
        // the distributed nodes are applied (to avoid unnecessary duplication of nodes)
        if (!otherOrNodeChildren.isEmpty()) {
            List<JexlNode> newChildren = new ArrayList<>();
            for (JexlNode newChild : nodesToDistribute) {
                newChildren.add(RebuildingVisitor.copy(newChild));
            }
            newChildren.add(createUnwrappedOrNode(otherOrNodeChildren));
            newOrNodeChildren.add(createUnwrappedAndNode(newChildren));
        }
        newOrNodes.add(createUnwrappedOrNode(newOrNodeChildren));
    }
    return createUnwrappedAndNode(newOrNodes);
}
Also used : ASTEQNode(org.apache.commons.jexl2.parser.ASTEQNode) ArrayList(java.util.ArrayList) ExceededValueThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededValueThresholdMarkerJexlNode) JexlNode(org.apache.commons.jexl2.parser.JexlNode)

Example 12 with JexlNodes.children

use of org.apache.commons.jexl2.parser.JexlNodes.children in project datawave by NationalSecurityAgency.

the class TreeFlatteningRebuilder method flattenTree.

/**
 * Given a stack of nodes, representing the post order traversal of a JexlNode, iteratively flattens the AND and OR nodes of the tree.
 *
 * @param postOrderStack
 *            the post order traversal representation of the tree
 * @return the flattened tree
 */
private JexlNode flattenTree(Deque<JexlNode> postOrderStack) {
    Deque<JexlNode> parentStack = new LinkedList<>();
    Deque<List<JexlNode>> childrenStack = new LinkedList<>();
    JexlNode newNode = null;
    // now that we have the post order traversal, we can operate on the nodes...
    while (!postOrderStack.isEmpty()) {
        JexlNode node = postOrderStack.pop();
        boolean hasChildren = node.jjtGetNumChildren() > 0;
        // if this is a reference node, flatten it
        if (hasChildren && node instanceof ASTReference) {
            newNode = flattenReference((ASTReference) JexlNodes.children(parentStack.pop(), childrenStack.pop().toArray(new JexlNode[0])));
        } else // if this is an AND or OR node, flatten it
        if (hasChildren && (node instanceof ASTOrNode || node instanceof ASTAndNode)) {
            newNode = flattenAndOrNode(JexlNodes.children(parentStack.pop(), childrenStack.pop().toArray(new JexlNode[0])));
        } else // if this is a node with children, assign the children
        if (hasChildren && node == parentStack.peek()) {
            newNode = JexlNodes.children(parentStack.pop(), childrenStack.pop().toArray(new JexlNode[0]));
        } else // if this is a leaf node, just keep it
        {
            newNode = node;
        }
        // if we still have nodes to evaluate
        if (!postOrderStack.isEmpty()) {
            // otherwise, add this node to the existing parent's list of children
            if (node.jjtGetParent() != parentStack.peek()) {
                parentStack.push(node.jjtGetParent());
                childrenStack.push(Lists.newArrayList(newNode));
            } else {
                childrenStack.peek().add(newNode);
            }
        }
    }
    return newNode;
}
Also used : ASTOrNode(org.apache.commons.jexl2.parser.ASTOrNode) JexlNode(org.apache.commons.jexl2.parser.JexlNode) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) LinkedList(java.util.LinkedList) ASTReference(org.apache.commons.jexl2.parser.ASTReference) ASTAndNode(org.apache.commons.jexl2.parser.ASTAndNode)

Example 13 with JexlNodes.children

use of org.apache.commons.jexl2.parser.JexlNodes.children in project datawave by NationalSecurityAgency.

the class TreeFlatteningRebuilder method flattenAndOrNode.

/**
 * Given an AND or OR node, this method will determine which child nodes can be merged into the parent node.
 *
 * @param node
 *            the node we are flattening into
 * @return the flattened version of node
 */
private JexlNode flattenAndOrNode(JexlNode node) {
    if (!(node instanceof ASTAndNode || node instanceof ASTOrNode)) {
        log.error("Only ASTAndNodes and ASTOrNodes can be flattened!");
        throw new RuntimeException("Only ASTAndNodes and ASTOrNodes can be flattened!");
    }
    // if the AND/OR node only has a single child, just return the child
    if (node.jjtGetNumChildren() == 1) {
        return node.jjtGetChild(0);
    } else // if there are multiple children, determine which ones can be flattened into the parent
    {
        Deque<JexlNode> children = new LinkedList<>();
        Deque<JexlNode> stack = new LinkedList<>();
        for (JexlNode child : children(node)) stack.push(child);
        while (!stack.isEmpty()) {
            JexlNode poppedNode = stack.pop();
            JexlNode dereferenced = JexlASTHelper.dereference(poppedNode);
            if (acceptableNodesToCombine(node, dereferenced, poppedNode != dereferenced)) {
                for (int i = 0; i < dereferenced.jjtGetNumChildren(); i++) {
                    stack.push(dereferenced.jjtGetChild(i));
                }
            } else {
                children.push(poppedNode);
            }
        }
        return JexlNodes.children(node, children.toArray(new JexlNode[0]));
    }
}
Also used : ASTOrNode(org.apache.commons.jexl2.parser.ASTOrNode) JexlNode(org.apache.commons.jexl2.parser.JexlNode) LinkedList(java.util.LinkedList) ASTAndNode(org.apache.commons.jexl2.parser.ASTAndNode)

Example 14 with JexlNodes.children

use of org.apache.commons.jexl2.parser.JexlNodes.children in project datawave by NationalSecurityAgency.

the class UniqueExpressionTermsVisitor method removeDuplicateNodes.

private JexlNode removeDuplicateNodes(JexlNode node, Object data) {
    // Traverse each child to de-dupe their children.
    // @formatter:off
    List<JexlNode> visitedChildren = Arrays.stream(children(node)).map(child -> (JexlNode) child.jjtAccept(this, data)).filter(Objects::nonNull).collect(Collectors.toList());
    // @formatter:on
    // Dedupe the visited children.
    List<JexlNode> uniqueChildren = getUniqueChildren(visitedChildren);
    if (uniqueChildren.size() == 1) {
        // If only one child remains, return it.
        return uniqueChildren.get(0);
    } else {
        // If two or more children remain, return a copy with the unique children.
        JexlNode copy = JexlNodes.newInstanceOfType(node);
        copy.image = node.image;
        copy.jjtSetParent(node.jjtGetParent());
        JexlNodes.children(copy, uniqueChildren.toArray(new JexlNode[0]));
        return copy;
    }
}
Also used : JexlNode(org.apache.commons.jexl2.parser.JexlNode)

Aggregations

JexlNode (org.apache.commons.jexl2.parser.JexlNode)14 ArrayList (java.util.ArrayList)8 ASTAndNode (org.apache.commons.jexl2.parser.ASTAndNode)7 ASTOrNode (org.apache.commons.jexl2.parser.ASTOrNode)6 ExceededValueThresholdMarkerJexlNode (datawave.query.jexl.nodes.ExceededValueThresholdMarkerJexlNode)3 LinkedList (java.util.LinkedList)3 ASTReference (org.apache.commons.jexl2.parser.ASTReference)3 ASTReferenceExpression (org.apache.commons.jexl2.parser.ASTReferenceExpression)3 BoundedRange (datawave.query.jexl.nodes.BoundedRange)2 List (java.util.List)2 ASTEQNode (org.apache.commons.jexl2.parser.ASTEQNode)2 ASTFunctionNode (org.apache.commons.jexl2.parser.ASTFunctionNode)2 IpAddressType (datawave.data.type.IpAddressType)1 Type (datawave.data.type.Type)1 DatawaveFatalQueryException (datawave.query.exceptions.DatawaveFatalQueryException)1 ContainerType (datawave.query.jexl.JexlNodeFactory.ContainerType)1 LiteralRange (datawave.query.jexl.LiteralRange)1 JexlArgumentDescriptor (datawave.query.jexl.functions.arguments.JexlArgumentDescriptor)1 QueryException (datawave.webservice.query.exception.QueryException)1 LinkedHashMap (java.util.LinkedHashMap)1