package org.bundlemaker.core.ui.editor.dsm.cycle; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; import org.bundlemaker.core.analysis.IBundleMakerArtifact; import org.bundlemaker.core.analysis.algorithms.Tarjan; import org.bundlemaker.core.analysis.algorithms.sorter.FastFasSorter; import org.bundlemaker.core.analysis.algorithms.sorter.IArtifactSorter; import org.eclipse.core.runtime.Assert; /** * <p> * </p> * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class CycleDetector { /** - */ private List<List<IBundleMakerArtifact>> _cycles; /** - */ private int[][] _cycleArray; /** - */ private IBundleMakerArtifact[] _artifacts; /** * <p> * Creates a new instance of type {@link CycleDetector}. * </p> * * @param unorderedArtifacts */ public CycleDetector(Collection<? extends IBundleMakerArtifact> unorderedArtifacts) { this(); initialize(unorderedArtifacts); } /** * <p> * Creates a new instance of type {@link CycleDetector}. * </p> */ public CycleDetector() { _cycleArray = new int[0][0]; _artifacts = new IBundleMakerArtifact[0]; } public IBundleMakerArtifact[] getOrderedArtifacts() { return _artifacts; } /** * {@inheritDoc} */ public boolean isInCycle(int i) { return isInCycle(i, i); } public boolean isInCycle(int i, int j) { // if (i < 0 || i >= _artifacts.length || j < 0 || j >= _artifacts.length) { return false; } // for (List<IBundleMakerArtifact> artifacts : _cycles) { if (artifacts.size() > 1 && artifacts.contains(_artifacts[i]) && artifacts.contains(_artifacts[j])) { return true; } } // return false; } /** * {@inheritDoc} */ public int[][] getCycles() { return _cycleArray; } public void initialize(Collection<? extends IBundleMakerArtifact> unorderedArtifacts) { // IArtifact[] headers, IDependency[][] dependencies Assert.isNotNull(unorderedArtifacts); _cycles = new Tarjan<IBundleMakerArtifact>().executeTarjan(unorderedArtifacts); IArtifactSorter artifactSorter = new FastFasSorter(); for (List<IBundleMakerArtifact> cycle : _cycles) { if (cycle.size() > 1) { artifactSorter.sort(cycle); } } // Map<IArtifact, Integer> artifactColumnMap = new HashMap<IArtifact, // Integer>(); List<IBundleMakerArtifact> orderedArtifacts = new ArrayList<IBundleMakerArtifact>(); // hack: un-cycled artifacts without dependencies first for (List<IBundleMakerArtifact> artifactList : _cycles) { if (artifactList.size() == 1 && artifactList.get(0).getDependenciesTo().size() == 0) { orderedArtifacts.add(artifactList.get(0)); } } // for (List<IBundleMakerArtifact> cycle : _cycles) { for (IBundleMakerArtifact iArtifact : cycle) { if (!orderedArtifacts.contains(iArtifact)) { orderedArtifacts.add(iArtifact); } } } Collections.reverse(orderedArtifacts); _artifacts = orderedArtifacts.toArray(new IBundleMakerArtifact[0]); // List<int[]> cycles = new LinkedList<int[]>(); for (List<IBundleMakerArtifact> artifactList : _cycles) { if (artifactList.size() > 1) { int[] cycle = new int[artifactList.size()]; for (int i = 0; i < cycle.length; i++) { cycle[cycle.length - (i + 1)] = orderedArtifacts.indexOf(artifactList.get(i)); } cycles.add(cycle); } } _cycleArray = cycles.toArray(new int[0][0]); } }