/** * Wraps some node in a ReferenceExpression, so when rebuilding, the subtree will be surrounded by parens */ public static ASTReferenceExpression wrap(JexlNode node) { ASTReferenceExpression ref = new ASTReferenceExpression(ParserTreeConstants.JJTREFERENCEEXPRESSION); return children(ref, node); }
/** * Wraps any node in a reference node. This is useful for getting rid of the boilerplate associated with wrapping an {ASTStringLiteral}. * * @param node * @return */ public static ASTReference makeRef(JexlNode node) { ASTReference ref = new ASTReference(ParserTreeConstants.JJTREFERENCE); return children(ref, node); }
private <T extends JexlNode> T copy(T node, Object data) { T newNode = newInstanceOfType(node); newNode.image = node.image; ArrayList<JexlNode> children = newArrayList(); for (JexlNode child : children(node)) { JexlNode copiedChild = (JexlNode) child.jjtAccept(this, data); if (copiedChild != null) { children.add(copiedChild); } } return children(newNode, children.toArray(new JexlNode[children.size()])); }
private static ASTIdentifier findIdentifier(JexlNode node) { if (node instanceof ASTIdentifier) { return (ASTIdentifier) node; } for (JexlNode child : JexlNodes.children(node)) { ASTIdentifier test = findIdentifier(child); if (test != null) { return test; } } return null; }
public static JexlNode findLiteral(JexlNode node) { if (node instanceof Literal<?>) { return node; } for (JexlNode child : JexlNodes.children(node)) { JexlNode test = findLiteral(child); if (test != null && test instanceof Literal<?>) { return test; } } return null; }
@Override public Object visit(ASTReference node, Object data) { ASTReference ref = (ASTReference) super.visit(node, data); if (JexlNodes.children(ref).length == 0) { return null; } else { return ref; } }
@Override public Object visit(ASTReferenceExpression node, Object data) { ASTReferenceExpression ref = (ASTReferenceExpression) super.visit(node, data); if (JexlNodes.children(ref).length == 0) { return null; } else { return ref; } }
@Override public Object visit(ASTFunctionNode node, Object data) { ASTFunctionNode newNode = newInstanceOfType(node); newNode.image = node.image; ArrayList<JexlNode> children = newArrayList(); JexlNode[] childNodes = children(node); for (int i = 0; i < childNodes.length; i++) { // passing in i-2 because the first function argument is actually at node 2. The first two // nodes are the namespace and function name. JexlNode copiedChild = (JexlNode) childNodes[i].jjtAccept(this, i); if (copiedChild != null) { children.add(copiedChild); } } return children(newNode, children.toArray(new JexlNode[0])); }
public static JexlNode otherChild(JexlNode parent, JexlNode child) { Preconditions.checkArgument(parent.jjtGetNumChildren() == 2, "Jexl tree must be binary, but received node with %s children.", parent.jjtGetNumChildren()); JexlNode otherChild = null; for (JexlNode n : children(parent)) if (child != n) otherChild = n; return Preconditions.checkNotNull(otherChild); }
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()])); } }
public void collapseAndSubtrees(ASTAndNode node, List<JexlNode> subTrees) { for (JexlNode child : children(node)) { if (ParserTreeConstants.JJTANDNODE == id(child)) { collapseAndSubtrees((ASTAndNode) child, subTrees); } else { subTrees.add(child); } } }
public void collapseAndSubtrees(ASTAndNode node, List<JexlNode> subTrees) { for (JexlNode child : children(node)) { if (ParserTreeConstants.JJTANDNODE == id(child)) { collapseAndSubtrees((ASTAndNode) child, subTrees); } else { subTrees.add(child); } } }
private JexlNode pushFunctionIntoExceededValueRange(JexlNode filter, JexlNode range) { JexlNode source = ExceededValueThresholdMarkerJexlNode.getExceededValueThresholdSource(range); source = JexlASTHelper.dereference(source); JexlNode parent = source.jjtGetParent(); ASTAndNode andNode = new ASTAndNode(ParserTreeConstants.JJTANDNODE); andNode = children(andNode, source, filter); children(parent, andNode); return range; }
public FunctionFilter(List<ASTFunctionNode> nodes) { ASTJexlScript script = new ASTJexlScript(ParserTreeConstants.JJTJEXLSCRIPT); if (nodes.size() > 1) { ASTAndNode andNode = new ASTAndNode(ParserTreeConstants.JJTANDNODE); children(script, andNode); children(andNode, nodes.toArray(new JexlNode[nodes.size()])); } else { children(script, nodes.get(0)); } String query = JexlStringBuildingVisitor.buildQuery(script); JexlArithmetic arithmetic = new DefaultArithmetic(); // Get a JexlEngine initialized with the correct JexlArithmetic for // this Document DatawaveJexlEngine engine = ArithmeticJexlEngines.getEngine(arithmetic); // Evaluate the JexlContext against the Script this.script = engine.createScript(query); }
private JexlNode pushFunctionIntoExceededValueRange(Collection<JexlNode> functions, JexlNode range) { JexlNode source = ExceededValueThresholdMarkerJexlNode.getExceededValueThresholdSource(range); source = JexlASTHelper.dereference(source); JexlNode parent = source.jjtGetParent(); ASTAndNode andNode = new ASTAndNode(ParserTreeConstants.JJTANDNODE); JexlNode[] allChildren = new JexlNode[functions.size() + 1]; int i = 0; allChildren[i++] = source; for (JexlNode function : functions) { allChildren[i++] = function; } andNode = children(andNode, allChildren); children(parent, andNode); return range; }
/** * The cases for OR and AND in `descendIntoSubtree` were almost equal, save for the initial value for expand and the operator used to join the results of * each child. I made this little macro doohickey to allow the differences between the two processes to be abstracted away. * */ private boolean computeExpansionForSubtree(JexlNode node, Join join, Map<JexlNode,Boolean> visited) { boolean expand = Join.AND.equals(join); for (JexlNode child : children(node)) { Boolean computedValue = visited.get(child); if (computedValue == null) { computedValue = descendIntoSubtree(child, visited); visited.put(child, computedValue); } switch (join) { case AND: expand &= computedValue; break; case OR: expand |= computedValue; } } visited.put(node, expand); return expand; }
public static ASTNotNode negate(JexlNode node) { return children(new ASTNotNode(ParserTreeConstants.JJTNOTNODE), wrap(node)); }
protected static Map<LiteralRange<?>,List<JexlNode>> getBoundedRanges(List<JexlNode> rangeNodes, List<JexlNode> nonIndexedRangeNodes, List<JexlNode> otherNodes) { // if the non-indexed range nodes were split out, then lets group them back into their AND expressions and put them in the // other node list (see getBoundedRanges vs. getBoundedRangesIndexAgnostic) if (nonIndexedRangeNodes != null && otherNodes != null) { Map<LiteralRange<?>,List<JexlNode>> ranges = getBoundedRanges(nonIndexedRangeNodes, otherNodes); for (List<JexlNode> range : ranges.values()) { // create a ref -> ref_exp -> and -> <range nodes> ASTAndNode andNode = new ASTAndNode(ParserTreeConstants.JJTANDNODE); andNode = JexlNodes.children(andNode, range.get(0), range.get(1)); ASTReferenceExpression refExpNode = JexlNodes.wrap(andNode); ASTReference refNode = JexlNodes.makeRef(refExpNode); otherNodes.add(refNode); } } return getBoundedRanges(rangeNodes, otherNodes); }