package org.simantics.modeling.requests; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Deque; import java.util.List; import org.eclipse.jface.viewers.IFilter; import org.simantics.scl.runtime.function.Function1; /** * @author Tuukka Lehtonen */ public class Nodes { public static Collection breadthFirstFlatten(IFilter filter, Collection roots) { Collection result = new ArrayList(); List sortedRoots = new ArrayList(roots); Collections.sort(sortedRoots); Deque todo = new ArrayDeque(sortedRoots); while (!todo.isEmpty()) { Node n = todo.removeFirst(); List sorted = new ArrayList(n.getChildren()); Collections.sort(sorted); todo.addAll(sorted); if (filter == null || filter.select(n)) result.add(n); } return result; } public static Collection depthFirstFlatten(IFilter filter, Collection roots, Comparator comparator) { Collection result = new ArrayList(); List sortedRoots = new ArrayList(roots); Collections.sort(sortedRoots, comparator); for (Node n : sortedRoots) { depthFirstFlattenRec(filter, comparator, n, result); } return result; } private static Collection depthFirstFlattenRec(IFilter filter, Comparator comparator, Node n, Collection result) { if (filter == null || filter.select(n)) result.add(n); Collection children = n.getChildren(); if (children.isEmpty()) return result; List sorted = new ArrayList(children); Collections.sort(sorted, comparator); for (Node child : sorted) depthFirstFlattenRec(filter, comparator, child, result); return result; } /** * @param f * function that takes the walked Node as argument and returns a * boolean to describe whether to continue the walk or cancel the * walk. The returned value cannot be null. * @return true if the walk was completed or false * if the walk was cancelled */ public static boolean walkTree(Function1 filter, Collection roots) { List sortedRoots = new ArrayList(roots); Collections.sort(sortedRoots); for (Node n : sortedRoots) if (!walkTreeRec(filter, n)) return false; return true; } private static boolean walkTreeRec(Function1 filter, Node n) { if (!filter.apply(n)) return false; Collection children = n.getChildren(); if (!children.isEmpty()) { List sorted = new ArrayList(children); Collections.sort(sorted); for (Node child : sorted) if (!walkTreeRec(filter, child)) return false; } return true; } }