Search in sources :

Example 1 with JexlNodes.children

use of org.apache.commons.jexl2.parser.JexlNodes.children 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);
}
Also used : ASTReferenceExpression(org.apache.commons.jexl2.parser.ASTReferenceExpression) ArrayList(java.util.ArrayList) ASTReference(org.apache.commons.jexl2.parser.ASTReference) LinkedHashMap(java.util.LinkedHashMap) JexlNode(org.apache.commons.jexl2.parser.JexlNode) ArrayList(java.util.ArrayList) List(java.util.List) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 2 with JexlNodes.children

use of org.apache.commons.jexl2.parser.JexlNodes.children 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;
}
Also used : ASTOrNode(org.apache.commons.jexl2.parser.ASTOrNode) ArrayList(java.util.ArrayList) JexlNode(org.apache.commons.jexl2.parser.JexlNode) LinkedList(java.util.LinkedList) ASTAndNode(org.apache.commons.jexl2.parser.ASTAndNode)

Example 3 with JexlNodes.children

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

the class WhindexVisitor method visit.

/**
 * Descends into each of the child nodes, and rebuilds the 'or' node with both the unmodified and modified nodes. Ancestor anded nodes are passed down to
 * each child, and the foundWhindex flag is passed up from the children.
 *
 * @param node
 *            An 'or' node from the original script
 * @param data
 *            ExpandData, containing ancestor anded nodes, used anded nodes, and a flag indicating whether whindexes were found
 * @return An expanded version of the 'or' node containing whindex nodes, if found, or the original in node, if not found
 */
@Override
public Object visit(ASTOrNode node, Object data) {
    ExpandData parentData = (ExpandData) data;
    // this shouldn't ever really happen, but it could
    if (node.jjtGetNumChildren() == 1)
        return super.visit(node, data);
    // iterate over the children and attempt to create whindexes
    List<JexlNode> unmodifiedNodes = new ArrayList<>();
    List<JexlNode> modifiedNodes = new ArrayList<>();
    List<String> modifiedNodesAsString = new ArrayList<>();
    for (JexlNode child : JexlNodes.children(node)) {
        ExpandData eData = new ExpandData();
        // add the anded leaf nodes from our ancestors
        eData.andedNodes.putAll(parentData.andedNodes);
        JexlNode processedNode = (JexlNode) child.jjtAccept(this, eData);
        String processedNodeAsString = JexlStringBuildingVisitor.buildQuery(processedNode);
        // and keep track of the used anded nodes
        if (eData.foundWhindex) {
            // the same final node. use this check to eliminate dupes
            if (!modifiedNodesAsString.contains(processedNodeAsString)) {
                modifiedNodes.add(processedNode);
                modifiedNodesAsString.add(processedNodeAsString);
                parentData.foundWhindex = true;
                parentData.usedAndedNodes.putAll(eData.usedAndedNodes);
            }
        } else
            unmodifiedNodes.add(child);
    }
    // otherwise, return the original or node
    if (parentData.foundWhindex) {
        List<JexlNode> processedNodes = new ArrayList<>();
        processedNodes.addAll(unmodifiedNodes);
        processedNodes.addAll(modifiedNodes);
        return createUnwrappedOrNode(processedNodes);
    } else
        return copy(node);
}
Also used : ArrayList(java.util.ArrayList) ExceededValueThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededValueThresholdMarkerJexlNode) JexlNode(org.apache.commons.jexl2.parser.JexlNode)

Example 4 with JexlNodes.children

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

the class FunctionJexlNodeVisitor method makeFunctionFrom.

public static ASTFunctionNode makeFunctionFrom(String ns, String functionName, JexlNode... arguments) {
    ASTFunctionNode fn = new ASTFunctionNode(ParserTreeConstants.JJTFUNCTIONNODE);
    ASTIdentifier namespace = JexlNodes.makeIdentifierWithImage(ns);
    ASTIdentifier function = JexlNodes.makeIdentifierWithImage(functionName);
    ArrayList<JexlNode> nodes = Lists.newArrayList();
    nodes.add(namespace);
    nodes.add(function);
    Collections.addAll(nodes, arguments);
    return JexlNodes.children(fn, nodes.toArray(new JexlNode[nodes.size()]));
}
Also used : ASTFunctionNode(org.apache.commons.jexl2.parser.ASTFunctionNode) ASTIdentifier(org.apache.commons.jexl2.parser.ASTIdentifier) JexlNode(org.apache.commons.jexl2.parser.JexlNode)

Example 5 with JexlNodes.children

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

the class ExpandMultiNormalizedTerms method expandRangeForNormalizers.

private Object expandRangeForNormalizers(LiteralRange<?> range, JexlNode node) {
    List<BoundedRange> aliasedBounds = Lists.newArrayList();
    String field = range.getFieldName();
    // Get all of the indexed or normalized dataTypes for the field name
    Set<Type<?>> dataTypes = Sets.newHashSet(config.getQueryFieldsDatatypes().get(field));
    dataTypes.addAll(config.getNormalizedFieldsDatatypes().get(field));
    for (Type<?> normalizer : dataTypes) {
        JexlNode lowerBound = range.getLowerNode(), upperBound = range.getUpperNode();
        JexlNode left = null;
        try {
            left = JexlASTHelper.applyNormalization(copy(lowerBound), normalizer);
        } catch (Exception ne) {
            if (log.isTraceEnabled()) {
                log.trace("Could not normalize " + PrintingVisitor.formattedQueryString(lowerBound) + " using " + normalizer.getClass() + ". " + ne.getMessage());
            }
            continue;
        }
        JexlNode right = null;
        try {
            right = JexlASTHelper.applyNormalization(copy(upperBound), normalizer);
        } catch (Exception ne) {
            if (log.isTraceEnabled()) {
                log.trace("Could not normalize " + PrintingVisitor.formattedQueryString(upperBound) + " using " + normalizer.getClass() + ". " + ne.getMessage());
            }
            continue;
        }
        aliasedBounds.add(new BoundedRange(JexlNodes.children(new ASTAndNode(ParserTreeConstants.JJTANDNODE), left, right)));
    }
    if (aliasedBounds.isEmpty()) {
        return node;
    } else {
        this.expandedNodes.addAll(aliasedBounds);
        // Avoid extra parens around the expansion
        if (1 == aliasedBounds.size()) {
            return aliasedBounds.get(0);
        } else {
            List<ASTReferenceExpression> var = JexlASTHelper.wrapInParens(aliasedBounds);
            return JexlNodes.wrap(JexlNodes.children(new ASTOrNode(ParserTreeConstants.JJTORNODE), var.toArray(new JexlNode[var.size()])));
        }
    }
}
Also used : ASTOrNode(org.apache.commons.jexl2.parser.ASTOrNode) ASTReferenceExpression(org.apache.commons.jexl2.parser.ASTReferenceExpression) ContainerType(datawave.query.jexl.JexlNodeFactory.ContainerType) IpAddressType(datawave.data.type.IpAddressType) Type(datawave.data.type.Type) JexlNode(org.apache.commons.jexl2.parser.JexlNode) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) QueryException(datawave.webservice.query.exception.QueryException) BoundedRange(datawave.query.jexl.nodes.BoundedRange) ASTAndNode(org.apache.commons.jexl2.parser.ASTAndNode)

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