package jetbrains.mps.ide.depanalyzer; /*Generated by MPS */ import jetbrains.mps.ide.ui.tree.MPSTree; import com.intellij.openapi.actionSystem.DataProvider; import java.util.List; import jetbrains.mps.internal.collections.runtime.ListSequence; import java.util.ArrayList; import jetbrains.mps.project.Project; import javax.swing.tree.TreeSelectionModel; import jetbrains.mps.internal.collections.runtime.Sequence; import java.util.Map; import jetbrains.mps.ide.depanalyzer.DependencyUtil.Dependency; import java.util.LinkedList; import jetbrains.mps.internal.collections.runtime.MapSequence; import jetbrains.mps.ide.ui.tree.MPSTreeNode; import jetbrains.mps.ide.ui.tree.TextTreeNode; import java.util.HashMap; import com.intellij.openapi.actionSystem.ActionGroup; import jetbrains.mps.workbench.action.ActionUtils; import jetbrains.mps.workbench.action.BaseAction; import com.intellij.openapi.actionSystem.ActionManager; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NonNls; import jetbrains.mps.ide.actions.MPSCommonDataKeys; import org.jetbrains.mps.openapi.module.SModule; public class DependencyPathTree extends MPSTree implements DataProvider { private List<DepLink> myAllDependencies = ListSequence.fromList(new ArrayList<DepLink>()); private final Project myProject; public DependencyPathTree(Project project) { myProject = project; getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); } public void resetDependencies() { ListSequence.fromList(myAllDependencies).clear(); } public void revealDependencies(Iterable<DepLink> node) { ListSequence.fromList(myAllDependencies).addSequence(Sequence.fromIterable(node)); } private void buildTree(DepLink depNode, Map<Dependency, DependencyPathTree.LinkFrom> visited) { List<DepLink> dependencyPath = ListSequence.fromList(new LinkedList<DepLink>()); // unwind up to source of depdendency path, effectively reversing it, top (source of dep) -> bottom (target of dep) while (depNode != null) { ListSequence.fromList(dependencyPath).insertElement(0, depNode); depNode = depNode.parent(); } DependencyPathTree.LinkFrom parent = null; while (ListSequence.fromList(dependencyPath).isNotEmpty()) { DepLink n = ListSequence.fromList(dependencyPath).removeElementAt(0); Dependency key = n.getRoleModuleKey(); DependencyPathTree.LinkFrom e = MapSequence.fromMap(visited).get(key); if (e == null || e.parent != parent) { // we didn't yet see that dep link anywhere, or have seen it under another branch DependencyPathTree.LinkFrom f = new DependencyPathTree.LinkFrom(n, parent, myProject); MapSequence.fromMap(visited).put(key, f); parent = f; } else { parent = e; } } if (parent != null) { // parent is the bottom (leaf) node, holding the module we initially selected (revealDependencies()) parent.node.setDepLeaf(); } } @Override protected MPSTreeNode rebuild() { MPSTreeNode result = new TextTreeNode((ListSequence.fromList(myAllDependencies).isEmpty() ? "No Dependencies Selected" : "Found Dependencies:")); Map<Dependency, DependencyPathTree.LinkFrom> deps = MapSequence.fromMap(new HashMap<Dependency, DependencyPathTree.LinkFrom>()); // merge dependency paths by role and module for (DepLink dep : ListSequence.fromList(myAllDependencies)) { buildTree(dep, deps); } // attach roots of merged paths to top node for (DependencyPathTree.LinkFrom lf : Sequence.fromIterable(MapSequence.fromMap(deps).values())) { if (lf.parent == null) { result.add(lf.node); } } setRootVisible(result.getChildCount() == 0); setShowsRootHandles(result.getChildCount() != 0); return result; } @Override protected ActionGroup createPopupActionGroup(MPSTreeNode node) { return ActionUtils.groupFromActions(((BaseAction) ActionManager.getInstance().getAction("jetbrains.mps.ide.actions.SafeDeleteModuleDependency_Action")), ((BaseAction) ActionManager.getInstance().getAction("jetbrains.mps.ide.actions.ShowInDependenciesViewer_Action")), ((BaseAction) ActionManager.getInstance().getAction("jetbrains.mps.ide.actions.ModuleProperties_Action"))); } @Nullable @Override public Object getData(@NonNls String id) { DependencyTreeNode current = as_9bg0dz_a0a0a8(getCurrentNode(), DependencyTreeNode.class); if (id.equals(MPSCommonDataKeys.TREE_NODE.getName())) { return current; } if (id.equals(MPSCommonDataKeys.MODULE.getName())) { return check_9bg0dz_a0a2a8(current); } return null; } public static class LinkFrom { /*package*/ DepLink link; /*package*/ DependencyPathTree.LinkFrom parent; /*package*/ DependencyTreeNode node; public LinkFrom(DepLink link, DependencyPathTree.LinkFrom from, Project project) { this.link = link; this.parent = from; node = new DependencyTreeNode(project, link); if (from != null) { from.node.add(node); } } } private static SModule check_9bg0dz_a0a2a8(DependencyTreeNode checkedDotOperand) { if (null != checkedDotOperand) { return checkedDotOperand.getModule(); } return null; } private static <T> T as_9bg0dz_a0a0a8(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } }