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);
}
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;
}
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]));
}
}
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;
}
}
Aggregations