use of org.apache.commons.jexl2.parser.ASTOrNode in project datawave by NationalSecurityAgency.
the class ExecutableExpansionVisitor method getOrTerms.
/**
* Get the list of breakout terms from an orNode where each term is Executable or is the grouping of non-executable elements in a new orNode, each bridged
* appropriately
*
* @param orNode
* the orNode to get expansion terms from
* @param bridgeFrom
* the JexlNode to begin all bridges or null if there should be no bridging
* @return a non-null list of bridged JexlNode that should be part of the expansion
*/
private List<JexlNode> getOrTerms(ASTOrNode orNode, JexlNode bridgeFrom) {
List<JexlNode> terms = new ArrayList<>();
List<JexlNode> nonExecutablePool = new ArrayList<>();
for (int i = 0; i < orNode.jjtGetNumChildren(); i++) {
JexlNode child = orNode.jjtGetChild(i);
if (ExecutableDeterminationVisitor.isExecutable(child, config, helper)) {
// break out
terms.add(bridge(child, bridgeFrom));
} else {
// add to pool of non-broken out
nonExecutablePool.add(child);
}
}
JexlNode poolNode = null;
// add the nonExecutablePool elements to a newOr that will be carried forward if there is more than one element
if (nonExecutablePool.size() > 1) {
poolNode = new ASTOrNode(ParserTreeConstants.JJTORNODE);
int childCount = 0;
for (JexlNode nonExecutableChild : nonExecutablePool) {
nonExecutableChild.jjtSetParent(poolNode);
poolNode.jjtAddChild(nonExecutableChild, childCount++);
}
} else {
poolNode = nonExecutablePool.get(0);
}
terms.add(bridge(poolNode, bridgeFrom));
return terms;
}
use of org.apache.commons.jexl2.parser.ASTOrNode in project datawave by NationalSecurityAgency.
the class DistributeAndedNodesVisitor method visit.
/**
* Checks each of the child nodes, and determines how the anded nodes should be applied.
*
* @param node
* The node that we will be distributing the anded nodes into
* @param data
* The nodes which we will be distributing into the root node
* @return An updated script with the anded nodes distributed throughout
*/
@Override
public Object visit(ASTOrNode node, Object data) {
DistributeAndedNodesVisitor.DistAndData parentData = (DistributeAndedNodesVisitor.DistAndData) data;
if (initialNode == null || initialNode instanceof ASTReference || initialNode instanceof ASTReferenceExpression)
initialNode = node;
// if this node is one of the anded nodes, or a whindex
// comprised of one of the anded nodes, halt recursion
List<JexlNode> usedAndedNodes = usesAndedNodes(node);
if (!usedAndedNodes.isEmpty()) {
parentData.usedAndedNodes.addAll(usedAndedNodes);
return node;
}
// this logic is dependent upon identifying whindex nodes by their address
if (whindexNodes.containsKey(node)) {
return node;
}
boolean rebuildNode = false;
// check each child node
List<JexlNode> nodesMissingEverything = new ArrayList<>();
List<JexlNode> nodesWithEverything = new ArrayList<>();
Map<JexlNode, List<JexlNode>> nodesMissingSomething = new LinkedHashMap<>();
for (JexlNode child : JexlNodes.children(node)) {
DistributeAndedNodesVisitor.DistAndData foundData = new DistributeAndedNodesVisitor.DistAndData();
JexlNode processedChild = (JexlNode) child.jjtAccept(this, foundData);
if (processedChild != child)
rebuildNode = true;
if (foundData.usedAndedNodes.isEmpty())
nodesMissingEverything.add(processedChild);
else if (!foundData.usedAndedNodes.containsAll(andedNodes)) {
List<JexlNode> missingAndedNodes = new ArrayList<>(andedNodes);
missingAndedNodes.removeAll(foundData.usedAndedNodes);
nodesMissingSomething.put(processedChild, missingAndedNodes);
} else
nodesWithEverything.add(processedChild);
}
// if none of the children are missing anything, we're done
if (nodesWithEverything.size() == node.jjtGetNumChildren()) {
parentData.usedAndedNodes.addAll(andedNodes);
if (rebuildNode)
return WhindexVisitor.createUnwrappedOrNode(nodesWithEverything);
else
return node;
} else // are missing everything, it implies that the children were left as-is
if (nodesMissingEverything.size() == node.jjtGetNumChildren()) {
return node;
}
// if we got here, then there are some nodes missing SOMETHING, and we have work to do
List<JexlNode> rebuiltChildren = new ArrayList<>();
// andedNodes
for (Map.Entry<JexlNode, List<JexlNode>> childEntry : nodesMissingSomething.entrySet()) rebuiltChildren.add(DistributeAndedNodesVisitor.distributeAndedNode(childEntry.getKey(), childEntry.getValue(), whindexNodes));
// for children missing everything -> 'or' them together, then 'and' them with the full set of andedNodes
List<JexlNode> nodeList = andedNodes.stream().map(RebuildingVisitor::copy).collect(Collectors.toList());
if (!nodesMissingEverything.isEmpty()) {
nodeList.add(WhindexVisitor.createUnwrappedOrNode(nodesMissingEverything));
}
rebuiltChildren.add(WhindexVisitor.createUnwrappedAndNode(nodeList));
// for children with everything -> keep those as-is
rebuiltChildren.addAll(nodesWithEverything);
parentData.usedAndedNodes.addAll(andedNodes);
return WhindexVisitor.createUnwrappedOrNode(rebuiltChildren);
}
use of org.apache.commons.jexl2.parser.ASTOrNode in project datawave by NationalSecurityAgency.
the class TreeFlatteningRebuilder method copyTree.
/**
* Iteratively creates a copy of the passed in JexlNode
*
* @param node
* the node to be copied
* @param postOrderDeque
* the post order traversal of the copied tree
* @return the copied tree
*/
private JexlNode copyTree(JexlNode node, Deque<JexlNode> postOrderDeque) {
// add all the nodes to the stack and iterate...
Deque<JexlNode> workingStack = new LinkedList<>();
// create a copy of this node which shares the same children as the original node
JexlNode copiedNode = rebuildNode(node);
workingStack.push(copiedNode);
// compute the post order traversal of all of the nodes, and copy them
while (!workingStack.isEmpty()) {
JexlNode poppedNode = workingStack.pop();
postOrderDeque.push(poppedNode);
// if this node has children, create copies of them
if (poppedNode.jjtGetNumChildren() > 0) {
List<JexlNode> copiedChildren = new ArrayList<>();
List<JexlNode> children = (poppedNode instanceof ASTAndNode || poppedNode instanceof ASTOrNode) ? getAndOrLeaves(poppedNode) : Arrays.asList(children(poppedNode));
for (JexlNode child : children) {
if (child != null) {
// create a copy of this node which shares the same children as the original node
JexlNode copiedChild = rebuildNode(child);
copiedChildren.add(copiedChild);
workingStack.push(copiedChild);
}
}
// Reassign the children for this copied node
JexlNodes.children(poppedNode, copiedChildren.toArray(new JexlNode[0]));
}
}
return copiedNode;
}
use of org.apache.commons.jexl2.parser.ASTOrNode in project datawave by NationalSecurityAgency.
the class TreeFlatteningRebuilder method getAndOrLeaves.
private List<JexlNode> getAndOrLeaves(JexlNode node) {
LinkedList<JexlNode> children = new LinkedList<>();
LinkedList<JexlNode> stack = new LinkedList<>();
stack.push(node);
while (!stack.isEmpty()) {
JexlNode currNode = stack.pop();
// @formatter:off
if (currNode == node || (node.getClass().isInstance(currNode) && (currNode instanceof ASTOrNode || (currNode instanceof ASTAndNode && !isBoundedRange((ASTAndNode) currNode))))) {
// @formatter:on
for (JexlNode child : children(currNode)) {
stack.push(child);
}
} else {
children.push(currNode);
}
}
return children;
}
use of org.apache.commons.jexl2.parser.ASTOrNode in project datawave by NationalSecurityAgency.
the class TreeWrappingRebuildingVisitor method visit.
@Override
public Object visit(ASTOrNode node, Object data) {
ASTOrNode newNode = new ASTOrNode(ParserTreeConstants.JJTORNODE);
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
JexlNode child = (JexlNode) node.jjtGetChild(i).jjtAccept(this, data);
newNode.jjtAddChild(child, newNode.jjtGetNumChildren());
child.jjtSetParent(newNode);
}
return JexlNodeFactory.wrap(newNode);
}
Aggregations