/** * Add the children JexlNodes to the parent JexlNode, correctly setting parent pointers, parenthesis, and reference nodes. * * @param parent * @param children * @return */ public static JexlNode setChildren(JexlNode parent, Iterable<? extends JexlNode> children) { int i = 0; JexlNodes.ensureCapacity(parent, Iterables.size(children)); // hopefully // we got // passed a // collection... for (JexlNode child : children) { parent.jjtAddChild(child, i); child.jjtSetParent(parent); i++; } return parent; }
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()])); } }
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()])); }
/** * 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); }
HashMap<String,JexlNode> lowerBounds = Maps.newHashMap(), upperBounds = Maps.newHashMap(); List<JexlNode> others = Lists.newArrayList(); for (JexlNode child : JexlNodes.children(smashed)) { switch (id(child)) { case ParserTreeConstants.JJTGENODE: case ParserTreeConstants.JJTGTNODE: aliasedBounds.add(JexlNodes.children(new ASTAndNode(ParserTreeConstants.JJTANDNODE), left, right)); others.add(JexlNodes.wrap(aliasedBounds.get(0))); } else { List<ASTReferenceExpression> var = JexlASTHelper.wrapInParens(aliasedBounds); others.add(JexlNodes.wrap(JexlNodes.children(new ASTOrNode(ParserTreeConstants.JJTORNODE), var.toArray(new JexlNode[var.size()])))); return super.visit(JexlNodes.children(smashed, others.toArray(new JexlNode[others.size()])), data);
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); }
@Override public Object visit(ASTAndNode node, Object data) { List<JexlNode> leaves = new ArrayList<>(); Map<LiteralRange<?>,List<JexlNode>> ranges = JexlASTHelper.getBoundedRangesIndexAgnostic(node, leaves, false); JexlNode andNode = JexlNodes.newInstanceOfType(node); andNode.image = node.image; andNode.jjtSetParent(node.jjtGetParent()); // We have a bounded range completely inside of an AND/OR if (!ranges.isEmpty()) { andNode = coalesceBoundedRanges(ranges, leaves, node, andNode, data); } else { // We have no bounded range to replace, just proceed as normal JexlNodes.ensureCapacity(andNode, node.jjtGetNumChildren()); for (int i = 0; i < node.jjtGetNumChildren(); i++) { JexlNode newChild = (JexlNode) node.jjtGetChild(i).jjtAccept(this, data); andNode.jjtAddChild(newChild, i); newChild.jjtSetParent(andNode); } } return andNode; }
JexlNode node = (JexlNode) script.jjtAccept(new TreeFlatteningRebuildingVisitor(true), script); if (JexlNodes.id(node) == ParserTreeConstants.JJTJEXLSCRIPT) { if (node.jjtGetNumChildren() != 1) { throw new IllegalArgumentException("Parsing failed for " + jexlQueryString); switch (JexlNodes.id(node)) {
Object data) { JexlNodes.ensureCapacity(newNode, leaves.size() + ranges.size()); int index = 0; for (; index < leaves.size(); index++) { JexlNodes.ensureCapacity(rangeNodes, range.getValue().size()); for (int i = 0; i < range.getValue().size(); i++) { rangeNodes.jjtAddChild(range.getValue().get(i), i); child = IndexHoleMarkerJexlNode.create(rangeNodes); } else { child = JexlNodes.wrap(rangeNodes);
int parentNodeChildCount = 0; JexlNodes.ensureCapacity(parentNode, fields.size()); for (String field : fields) { ValueSet valuesForField = fieldsToValues.get(field); 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)); 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); case 1: JexlNode child = parentNode.jjtGetChild(0); JexlNodes.promote(parentNode, child); return child; default:
@Override public Object visit(ASTOrNode node, Object data) { ASTOrNode orNode = JexlNodes.newInstanceOfType(node); orNode.image = node.image; return flattenTree(node, orNode, data); }
@Override public Object visit(ASTAndNode node, Object data) { ASTAndNode newNode = new ASTAndNode(ParserTreeConstants.JJTANDNODE); newNode.image = node.image; visit(node, newNode, data); switch (newNode.jjtGetNumChildren()) { case 0: return null; case 1: JexlNode child = newNode.jjtGetChild(0); JexlNodes.promote(newNode, child); return child; default: return newNode; } }
public static ASTReference literal(String s) { ASTStringLiteral l = new ASTStringLiteral(ParserTreeConstants.JJTSTRINGLITERAL); l.image = s; return makeRef(l); }
@Override public Object visit(ASTNumberLiteral node, Object data) { JexlNode op = node.jjtGetParent(); if (op instanceof ASTEQNode) { JexlNode field = JexlNodes.otherChild(op, node).jjtGetChild(0); values.addLiteral(node.getLiteral().toString(), JexlASTHelper.deconstructIdentifier(field.image)); } return null; }
/** * Sets the supplied child array as the children member of {node} and sets the parent reference of each element in {children} to {node}. * * @param node * @param children * @return */ public static <T extends JexlNode> T children(T node, JexlNode... children) { node.children = children; for (JexlNode child : node.children) newParent(child, node); return 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); }