| /******************************************************************************* |
| * Copyright (c) 2011 VMware Inc. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * SpringSource, a division of VMware - initial API and implementation and/or initial documentation |
| *******************************************************************************/ |
| |
| package org.eclipse.equinox.internal.region; |
| |
| import org.eclipse.equinox.region.Region; |
| import org.eclipse.equinox.region.RegionDigraphVisitor; |
| import org.eclipse.equinox.region.RegionDigraph.FilteredRegion; |
| |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| /** |
| * {@link SubgraphTraverser} is a utility for traversing a subgraph of a {@link RegionDigraph} calling a |
| * {@link RegionDigraphVisitor} on the way. |
| * <p /> |
| * |
| * <strong>Concurrent Semantics</strong><br /> |
| * Thread safe. |
| */ |
| final class SubgraphTraverser { |
| |
| void visitSubgraph(Region startingRegion, RegionDigraphVisitor visitor) { |
| visitRemainingSubgraph(startingRegion, visitor, new HashSet<Region>()); |
| } |
| |
| private void visitRemainingSubgraph(Region r, RegionDigraphVisitor visitor, Set<Region> path) { |
| if (!path.contains(r)) { |
| if (visitor.visit(r)) { |
| traverseEdges(r, visitor, path); |
| } |
| } |
| } |
| |
| private void traverseEdges(Region r, RegionDigraphVisitor visitor, Set<Region> path) { |
| for (FilteredRegion fr : r.getEdges()) { |
| if (visitor.preEdgeTraverse(fr.getFilter())) { |
| try { |
| visitRemainingSubgraph(fr.getRegion(), visitor, extendPath(r, path)); |
| } finally { |
| visitor.postEdgeTraverse(fr.getFilter()); |
| } |
| } |
| } |
| } |
| |
| private Set<Region> extendPath(Region r, Set<Region> path) { |
| Set<Region> newPath = new HashSet<Region>(path); |
| newPath.add(r); |
| return newPath; |
| } |
| |
| } |