/** * Tries to decompose a tree of binary operations into a list of operands. (A && B && C) or * (A || B || C) or (A + B + C) => [A, B, C] */ public static List<FormulaNode> findBinaryTree(FormulaNode rootNode, FormulaFunction operator) { List<FormulaNode> list = new ArrayList<>(); findBinaryTree(rootNode, list, operator); return list; }
public Multimap<Integer, FilterConfig> parseFilter(FormulaNode filter) { Multimap<Integer, FilterConfig> result = HashMultimap.create(); List<FormulaNode> nodes = Formulas.findBinaryTree(filter, AndFunction.INSTANCE); for (FormulaNode node : nodes) { if(!parseNode(node, result)) { return EMPTY; } } return result; }
private List<FormulaNode> parsePermission(String filter) { FormulaNode formulaNode = FormulaParser.parse(filter); return Formulas.findBinaryTree(formulaNode, AndFunction.INSTANCE); }
private static void findBinaryTree(FormulaNode node, List<FormulaNode> list, FormulaFunction operator) { // Unwrap group expressions ((A)) node = simplify(node); if(isBinaryOperation(node, operator)) { // If this expression is in the form A && B, then descend // recursively FunctionCallNode callNode = (FunctionCallNode) node; findBinaryTree(callNode.getArgument(0), list, operator); findBinaryTree(callNode.getArgument(1), list, operator); } else { // If not a conjunction, then add this node to the list list.add(node); } }
@Test public void decomposition() { assertThat(Formulas.findBinaryTree(parse("A && B"), AND), contains(A, B)); assertThat(Formulas.findBinaryTree(parse("A && B && C"), AND), contains(A, B, C)); assertThat(Formulas.findBinaryTree(parse("A && (B && C)"), AND), contains(A, B, C)); assertThat(Formulas.findBinaryTree(parse("(A && ((B && (C))))"), AND), contains(A, B, C)); }
List<FormulaNode> terms = Formulas.findBinaryTree(node, OrFunction.INSTANCE);