Search in sources :

Example 1 with ValueSet

use of datawave.query.jexl.lookups.ValueSet in project datawave by NationalSecurityAgency.

the class JexlNodeFactory method createNodeTreeFromFieldsToValues.

/**
 * Expand a node given a mapping of fields to values. If the list is empty, then the original regex should be used.
 *
 * @param containerType
 *            should we create OR nodes or AND nodes
 * @param node
 * @param fieldsToValues
 *            A mapping of fields to values. If the values for a field is empty, then the original regex should be used.
 * @param expandFields
 *            Expand fields if true
 * @param expandValues
 *            Expand values if true
 * @param keepOriginalNode
 *            Keep the original node along with any expansions
 * @return A new sub query
 */
public static JexlNode createNodeTreeFromFieldsToValues(ContainerType containerType, JexlNode node, JexlNode orgNode, IndexLookupMap fieldsToValues, boolean expandFields, boolean expandValues, boolean keepOriginalNode) {
    // do nothing if not expanding fields or values
    if (!expandFields && !expandValues) {
        return orgNode;
    }
    // no expansions needed if the fieldname threshold is exceeded
    if (fieldsToValues.isKeyThresholdExceeded()) {
        return new ExceededTermThresholdMarkerJexlNode(orgNode);
    }
    // collapse the value sets if not expanding fields
    if (!expandFields) {
        ValueSet allValues = new ValueSet(-1);
        for (ValueSet values : fieldsToValues.values()) {
            allValues.addAll(values);
        }
        fieldsToValues.clear();
        for (String identifier : JexlASTHelper.getIdentifierNames(orgNode)) {
            fieldsToValues.put(identifier, allValues);
        }
    }
    Set<String> fields = fieldsToValues.keySet();
    JexlNode parentNode = (containerType.equals(ContainerType.OR_NODE) ? new ASTOrNode(ParserTreeConstants.JJTORNODE) : new ASTAndNode(ParserTreeConstants.JJTANDNODE));
    int parentNodeChildCount = 0;
    if (keepOriginalNode) {
        JexlNodes.ensureCapacity(parentNode, fields.size() + 1);
        JexlNode child = RebuildingVisitor.copy(orgNode);
        parentNode.jjtAddChild(child, parentNodeChildCount);
        child.jjtSetParent(parentNode);
        parentNodeChildCount++;
        // remove this entry from the fieldsToValues to avoid duplication
        for (String identifier : JexlASTHelper.getIdentifierNames(orgNode)) {
            for (Object value : JexlASTHelper.getLiteralValues(orgNode)) {
                fieldsToValues.remove(identifier, value);
            }
        }
    } else {
        JexlNodes.ensureCapacity(parentNode, fields.size());
    }
    for (String field : fields) {
        ValueSet valuesForField = fieldsToValues.get(field);
        // if not expanding values, then reuse the original node with simply a new field name (anyfield only)
        if (!expandValues) {
            JexlNode child = RebuildingVisitor.copy(orgNode);
            for (ASTIdentifier identifier : JexlASTHelper.getIdentifiers(child)) {
                if (identifier.image.equals(Constants.ANY_FIELD)) {
                    identifier.image = field;
                }
            }
            parentNode.jjtAddChild(child, parentNodeChildCount);
            child.jjtSetParent(parentNode);
            parentNodeChildCount++;
        } else // node with a new fieldname, wrapped with a marker node
        if (valuesForField.isThresholdExceeded()) {
            // create a set of nodes wrapping each pattern
            List<String> patterns = new ArrayList<>(fieldsToValues.getPatterns() == null ? new ArrayList<>() : fieldsToValues.getPatterns());
            if (patterns.isEmpty()) {
                JexlNode child = new ExceededValueThresholdMarkerJexlNode(buildUntypedNode(orgNode, field));
                parentNode.jjtAddChild(child, parentNodeChildCount);
                child.jjtSetParent(parentNode);
                parentNodeChildCount++;
            } else if (patterns.size() == 1) {
                JexlNode child = new ExceededValueThresholdMarkerJexlNode(buildUntypedNode(orgNode, field, patterns.get(0)));
                parentNode.jjtAddChild(child, parentNodeChildCount);
                child.jjtSetParent(parentNode);
                parentNodeChildCount++;
            } else {
                int childNodeChildCount = 0;
                JexlNode childNode = (containerType.equals(ContainerType.OR_NODE) ? new ASTOrNode(ParserTreeConstants.JJTORNODE) : new ASTAndNode(ParserTreeConstants.JJTANDNODE));
                JexlNodes.ensureCapacity(childNode, patterns.size());
                for (String pattern : patterns) {
                    JexlNode child = new ExceededValueThresholdMarkerJexlNode(buildUntypedNode(orgNode, field, pattern));
                    childNode.jjtAddChild(child, childNodeChildCount);
                    child.jjtSetParent(childNode);
                    childNodeChildCount++;
                }
                if (0 < childNodeChildCount) {
                    JexlNode wrappedChildNode = wrap(childNode);
                    childNode.jjtSetParent(wrappedChildNode);
                    parentNode.jjtAddChild(wrappedChildNode, parentNodeChildCount);
                    childNode.jjtSetParent(childNode);
                    parentNodeChildCount++;
                }
            }
        } else // Don't create an OR if we have only one value, directly attach it
        if (1 == valuesForField.size()) {
            JexlNode child = buildUntypedNode(node, field, valuesForField.iterator().next());
            parentNode.jjtAddChild(child, parentNodeChildCount);
            child.jjtSetParent(parentNode);
            parentNodeChildCount++;
        } else {
            int childNodeChildCount = 0;
            JexlNode childNode = (containerType.equals(ContainerType.OR_NODE) ? new ASTOrNode(ParserTreeConstants.JJTORNODE) : new ASTAndNode(ParserTreeConstants.JJTANDNODE));
            JexlNodes.ensureCapacity(childNode, valuesForField.size());
            for (String value : valuesForField) {
                JexlNode child = buildUntypedNode(node, field, value);
                childNode.jjtAddChild(child, childNodeChildCount);
                child.jjtSetParent(childNode);
                childNodeChildCount++;
            }
            if (0 < childNodeChildCount) {
                JexlNode wrappedChildNode = wrap(childNode);
                childNode.jjtSetParent(wrappedChildNode);
                parentNode.jjtAddChild(wrappedChildNode, parentNodeChildCount);
                childNode.jjtSetParent(childNode);
                parentNodeChildCount++;
            }
        }
    }
    switch(parentNodeChildCount) {
        case 0:
            // in this case we had no matches for the range, so this expression gets replaced with a FALSE node.
            return new ASTFalseNode(ParserTreeConstants.JJTFALSENODE);
        case 1:
            JexlNode child = parentNode.jjtGetChild(0);
            JexlNodes.promote(parentNode, child);
            return child;
        default:
            JexlNode wrappedParentNode = wrap(parentNode);
            parentNode.jjtSetParent(wrappedParentNode);
            return wrappedParentNode;
    }
}
Also used : ASTOrNode(org.apache.commons.jexl2.parser.ASTOrNode) ASTIdentifier(org.apache.commons.jexl2.parser.ASTIdentifier) ExceededValueThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededValueThresholdMarkerJexlNode) ASTFalseNode(org.apache.commons.jexl2.parser.ASTFalseNode) ExceededTermThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededTermThresholdMarkerJexlNode) ExceededValueThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededValueThresholdMarkerJexlNode) JexlNode(org.apache.commons.jexl2.parser.JexlNode) ExceededTermThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededTermThresholdMarkerJexlNode) List(java.util.List) ArrayList(java.util.ArrayList) ValueSet(datawave.query.jexl.lookups.ValueSet) ASTAndNode(org.apache.commons.jexl2.parser.ASTAndNode)

Aggregations

ValueSet (datawave.query.jexl.lookups.ValueSet)1 ExceededTermThresholdMarkerJexlNode (datawave.query.jexl.nodes.ExceededTermThresholdMarkerJexlNode)1 ExceededValueThresholdMarkerJexlNode (datawave.query.jexl.nodes.ExceededValueThresholdMarkerJexlNode)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 ASTAndNode (org.apache.commons.jexl2.parser.ASTAndNode)1 ASTFalseNode (org.apache.commons.jexl2.parser.ASTFalseNode)1 ASTIdentifier (org.apache.commons.jexl2.parser.ASTIdentifier)1 ASTOrNode (org.apache.commons.jexl2.parser.ASTOrNode)1 JexlNode (org.apache.commons.jexl2.parser.JexlNode)1