/** * {@inheritDoc} * @deprecated prefer {@link #setup(FlowNode)} */ @Deprecated @Override public boolean setup(Collection<FlowNode> heads) { return super.setup(heads); }
/** * Helper: version of {@link #setup(Collection, Collection)} where we don't have any nodes to blacklist */ public boolean setup(@CheckForNull Collection<FlowNode> heads) { if (heads == null) { return false; } return setup(heads, Collections.EMPTY_SET); }
/** * {@inheritDoc} * @deprecated prefer {@link #setup(FlowNode, Collection)} */ @Deprecated @Override public boolean setup(Collection<FlowNode> heads, Collection<FlowNode> blackList) { return super.setup(heads, blackList); }
/** * Helper: version of {@link #setup(Collection, Collection)} where we don't have any nodes to blacklist, and have just a single head */ public boolean setup(@CheckForNull FlowNode head, @CheckForNull Collection<FlowNode> blackList) { if (head == null) { return false; } return setup(Collections.singleton(head), blackList); }
/** Convenience method to get the list all flownodes in the iterator order. */ @Nonnull public List<FlowNode> allNodes(@CheckForNull Collection<FlowNode> heads) { if (!setup(heads)) { return Collections.EMPTY_LIST; } List<FlowNode> nodes = new ArrayList<FlowNode>(); for (FlowNode f : this) { nodes.add(f); } return nodes; }
/** * Helper: version of {@link #setup(Collection, Collection)} where we don't have any nodes to blacklist and have just a single head */ public boolean setup(@CheckForNull FlowNode head) { if (head == null) { return false; } return setup(Collections.singleton(head), Collections.EMPTY_SET); }
/** * Find the first FlowNode within the iteration order matching a given condition * Includes null-checking on arguments to allow directly calling with unchecked inputs (simplifies use). * @param heads Head nodes to start walking from * @param blackListNodes Nodes that are never visited, search stops here (bound is exclusive). * If you want to create an inclusive bound, just use a node's parents. * @param matchCondition Predicate to match when we've successfully found a given node type * @return First matching node, or null if no matches found */ @CheckForNull public FlowNode findFirstMatch(@CheckForNull Collection<FlowNode> heads, @CheckForNull Collection<FlowNode> blackListNodes, Predicate<FlowNode> matchCondition) { if (!setup(heads, blackListNodes)) { return null; } for (FlowNode f : this) { if (matchCondition.apply(f)) { return f; } } return null; }
/** * Return a filtered list of {@link FlowNode}s matching a condition, in the order encountered. * Includes null-checking on arguments to allow directly calling with unchecked inputs (simplifies use). * @param heads Nodes to start iterating backward from by visiting their parents. * @param blackList Nodes we may not visit or walk beyond. * @param matchCondition Predicate that must be met for nodes to be included in output. Input is always non-null. * @return List of flownodes matching the predicate. */ @Nonnull public List<FlowNode> filteredNodes(@CheckForNull Collection<FlowNode> heads, @CheckForNull Collection<FlowNode> blackList, Predicate<FlowNode> matchCondition) { if (!setup(heads, blackList)) { return Collections.EMPTY_LIST; } ArrayList<FlowNode> nodes = new ArrayList<FlowNode>(); for (FlowNode f : this) { if (matchCondition.apply(f)) { nodes.add(f); } } return nodes; }
/** * Given a {@link FlowNodeVisitor}, invoke {@link FlowNodeVisitor#visit(FlowNode)} on each node and halt early if it returns false. * Includes null-checking on all but the visitor, to allow directly calling with unchecked inputs (simplifies use). * * Useful if you wish to collect some information from every node in the FlowGraph. * To do that, accumulate internal state in the visitor, and invoke a getter when complete. * @param heads Nodes to start walking the DAG backwards from. * @param blackList Nodes we can't visit or pass beyond. * @param visitor Visitor that will see each FlowNode encountered. */ public void visitAll(@CheckForNull Collection<FlowNode> heads, @CheckForNull Collection<FlowNode> blackList, @Nonnull FlowNodeVisitor visitor) { if (!setup(heads, blackList)) { return; } for (FlowNode f : this) { boolean canContinue = visitor.visit(f); if (!canContinue) { break; } } }