// Copyright 2014 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). package com.twitter.intellij.pants.projectview; import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.projectView.TreeStructureProvider; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; import com.intellij.ide.projectView.impl.nodes.PsiFileNode; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; import com.twitter.intellij.pants.util.PantsUtil; import icons.PantsIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Optional; public class PantsTreeStructureProvider implements TreeStructureProvider { @NotNull @Override public Collection<AbstractTreeNode> modify( @NotNull final AbstractTreeNode node, @NotNull Collection<AbstractTreeNode> collection, ViewSettings settings ) { final Project project = node.getProject(); if (node instanceof PsiDirectoryNode && project != null) { final Module module = ModuleUtil.findModuleForPsiElement(((PsiDirectoryNode) node).getValue()); final Optional<String> buildPath = module != null ? PantsUtil.getPathFromAddress(module, ExternalSystemConstants.LINKED_PROJECT_PATH_KEY) : Optional.empty(); if (buildPath.isPresent()) { final Optional<VirtualFile> buildFile = PantsUtil.findFileRelativeToBuildRoot(project, buildPath.get()); boolean isModuleRoot = ArrayUtil.indexOf(ModuleRootManager.getInstance(module).getContentRoots(), ((PsiDirectoryNode) node).getVirtualFile()) >= 0; if (buildFile.isPresent() && isModuleRoot) { // Check if there's already a BUILD file in the directory; if so, we don't add another final AbstractTreeNode existingBuildFile = ContainerUtil.find( collection.iterator(), new Condition<AbstractTreeNode>() { @Override public boolean value(AbstractTreeNode node) { return node instanceof PsiFileNode && buildFile.get().equals(((PsiFileNode) node).getVirtualFile()); } } ); if (existingBuildFile == null) { final PsiFile buildPsiFile = PsiManager.getInstance(project).findFile(buildFile.get()); final PsiFileNode buildNode = new PsiFileNode(project, buildPsiFile, settings) { @Override protected void updateImpl(PresentationData data) { super.updateImpl(data); data.setIcon(PantsIcons.Icon); } }; final List<AbstractTreeNode> modifiedCollection = new ArrayList<AbstractTreeNode>(collection); modifiedCollection.add(buildNode); return modifiedCollection; } } } } return collection; } @Nullable @Override public Object getData(Collection<AbstractTreeNode> collection, String s) { return null; } }