1 package org.simantics.modeling.requests;
3 import java.util.ArrayDeque;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Collections;
7 import java.util.Comparator;
8 import java.util.Deque;
11 import java.util.TreeSet;
12 import java.util.function.Predicate;
14 import org.eclipse.jface.viewers.IFilter;
15 import org.simantics.scl.runtime.function.Function1;
18 * @author Tuukka Lehtonen
22 public static final Predicate<Node> DIAGRAM_RESOURCE_PREDICATE = n -> n.getDiagramResource() != null;
23 public static final Predicate<Node> DIAGRAM_RESOURCE_AND_RVI_PREDICATE = n -> n.getDiagramResource() != null && n.getRVI() != null;
25 public static Collection<Node> breadthFirstFlatten(IFilter filter, Collection<Node> roots) {
26 Collection<Node> result = new ArrayList<>();
27 List<Node> sortedRoots = new ArrayList<>(roots);
28 Collections.sort(sortedRoots);
29 Deque<Node> todo = new ArrayDeque<>(sortedRoots);
30 while (!todo.isEmpty()) {
31 Node n = todo.removeFirst();
32 List<Node> sorted = new ArrayList<>(n.getChildren());
33 Collections.sort(sorted);
35 if (filter == null || filter.select(n))
41 public static Collection<Node> depthFirstFlatten(IFilter filter, Collection<Node> roots, Comparator<? super Node> comparator) {
42 Collection<Node> result = new ArrayList<>();
43 List<Node> sortedRoots = new ArrayList<>(roots);
44 Collections.sort(sortedRoots, comparator);
45 for (Node n : sortedRoots) {
46 depthFirstFlattenRec(filter, comparator, n, result);
51 private static Collection<Node> depthFirstFlattenRec(IFilter filter, Comparator<? super Node> comparator, Node n, Collection<Node> result) {
52 if (filter == null || filter.select(n))
55 Collection<Node> children = n.getChildren();
56 if (children.isEmpty())
59 List<Node> sorted = new ArrayList<>(children);
60 Collections.sort(sorted, comparator);
61 for (Node child : sorted)
62 depthFirstFlattenRec(filter, comparator, child, result);
69 * function that takes the walked Node as argument and returns a
70 * boolean to describe whether to continue the walk or cancel the
71 * walk. The returned value cannot be <code>null</code>.
72 * @return <code>true</code> if the walk was completed or <code>false</code>
73 * if the walk was cancelled
75 public static boolean walkTree(Function1<Node, Boolean> filter, Collection<Node> roots) {
76 List<Node> sortedRoots = new ArrayList<>(roots);
77 Collections.sort(sortedRoots);
78 for (Node n : sortedRoots)
79 if (!walkTreeRec(filter, n))
84 private static boolean walkTreeRec(Function1<Node, Boolean> filter, Node n) {
88 Collection<Node> children = n.getChildren();
89 if (!children.isEmpty()) {
90 List<Node> sorted = new ArrayList<>(children);
91 Collections.sort(sorted);
92 for (Node child : sorted)
93 if (!walkTreeRec(filter, child))
99 public static boolean parentIsInSet(Set<Node> set, Node node) {
100 for (Node n = node.getParent(); n != null; n = n.getParent())
106 public static Set<Node> depthFirstFilter(Predicate<Node> filter, Collection<Node> nodes) {
107 Set<Node> result = new TreeSet<>(Node.CASE_INSENSITIVE_COMPARATOR);
108 for (Node n : nodes) {
109 Node newNode = depthFirstFilterRec(filter, n, null);
116 public static Node depthFirstFilter(Predicate<Node> filter, Node n) {
117 return depthFirstFilterRec(filter, n, null);
120 private static Node depthFirstFilterRec(Predicate<Node> filter, Node n, Node newParent) {
121 Collection<Node> children = n.getChildren();
122 if (children.isEmpty())
123 return filter.test(n) ? n.cloneWithoutChildren(newParent) : null;
125 Node newNode = n.cloneWithoutChildren(newParent);
127 for (Node child : children) {
128 Node newChild = depthFirstFilterRec(filter, child, newNode);
129 if (newChild != null)
133 return childCount > 0 ? newNode : null;