blob: 04e93ac9e0e2e69ffc46bfab5f4fd4918e811b27 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.maven.navigator;
import com.intellij.execution.Location;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.ide.dnd.FileCopyPasteUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.treeStructure.SimpleNode;
import com.intellij.ui.treeStructure.SimpleTree;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.execution.MavenGoalLocation;
import org.jetbrains.idea.maven.model.MavenArtifact;
import org.jetbrains.idea.maven.model.MavenConstants;
import org.jetbrains.idea.maven.model.MavenProfileKind;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.utils.MavenDataKeys;
import org.jetbrains.idea.maven.utils.actions.MavenActionUtil;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.List;
public class MavenProjectsNavigatorPanel extends SimpleToolWindowPanel implements DataProvider {
private final Project myProject;
private final SimpleTree myTree;
private final Comparator<String> myGoalOrderComparator = new Comparator<String>() {
private Map<String, Integer> standardGoalOrder;
public int compare(String o1, String o2) {
return getStandardGoalOrder(o1) - getStandardGoalOrder(o2);
}
private int getStandardGoalOrder(String goal) {
if (standardGoalOrder == null) {
standardGoalOrder = new THashMap<String, Integer>();
int i = 0;
for (String aGoal : MavenConstants.PHASES) {
standardGoalOrder.put(aGoal, i++);
}
}
Integer order = standardGoalOrder.get(goal);
return order != null ? order.intValue() : standardGoalOrder.size();
}
};
public MavenProjectsNavigatorPanel(Project project, SimpleTree tree) {
super(true, true);
myProject = project;
myTree = tree;
final ActionManager actionManager = ActionManager.getInstance();
ActionToolbar actionToolbar = actionManager.createActionToolbar("Maven Navigator Toolbar",
(DefaultActionGroup)actionManager
.getAction("Maven.NavigatorActionsToolbar"),
true);
actionToolbar.setTargetComponent(tree);
setToolbar(actionToolbar.getComponent());
setContent(ScrollPaneFactory.createScrollPane(myTree));
setTransferHandler(new MyTransferHandler(project));
myTree.addMouseListener(new PopupHandler() {
public void invokePopup(final Component comp, final int x, final int y) {
final String id = getMenuId(getSelectedNodes(MavenProjectsStructure.MavenSimpleNode.class));
if (id != null) {
final ActionGroup actionGroup = (ActionGroup)actionManager.getAction(id);
if (actionGroup != null) {
actionManager.createActionPopupMenu("", actionGroup).getComponent().show(comp, x, y);
}
}
}
@Nullable
private String getMenuId(Collection<? extends MavenProjectsStructure.MavenSimpleNode> nodes) {
String id = null;
for (MavenProjectsStructure.MavenSimpleNode node : nodes) {
String menuId = node.getMenuId();
if (menuId == null) {
return null;
}
if (id == null) {
id = menuId;
}
else if (!id.equals(menuId)) {
return null;
}
}
return id;
}
});
}
@Nullable
public Object getData(@NonNls String dataId) {
if (PlatformDataKeys.HELP_ID.is(dataId)) return "reference.toolWindows.mavenProjects";
if (CommonDataKeys.PROJECT.is(dataId)) return myProject;
if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) return extractVirtualFile();
if (CommonDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) return extractVirtualFiles();
if (Location.DATA_KEY.is(dataId)) return extractLocation();
if (CommonDataKeys.NAVIGATABLE_ARRAY.is(dataId)) return extractNavigatables();
if (MavenDataKeys.MAVEN_GOALS.is(dataId)) return extractGoals(true);
if (MavenDataKeys.RUN_CONFIGURATION.is(dataId)) return extractRunSettings();
if (MavenDataKeys.MAVEN_PROFILES.is(dataId)) return extractProfiles();
if (MavenDataKeys.MAVEN_DEPENDENCIES.is(dataId)) {
return extractDependencies();
}
if (MavenDataKeys.MAVEN_PROJECTS_TREE.is(dataId)) {
return myTree;
}
return super.getData(dataId);
}
private VirtualFile extractVirtualFile() {
for (MavenProjectsStructure.MavenSimpleNode each : getSelectedNodes(MavenProjectsStructure.MavenSimpleNode.class)) {
VirtualFile file = each.getVirtualFile();
if (file != null && file.isValid()) return file;
}
final MavenProjectsStructure.ProjectNode projectNode = getContextProjectNode();
if (projectNode == null) return null;
VirtualFile file = projectNode.getVirtualFile();
if (file == null || !file.isValid()) return null;
return file;
}
private Object extractVirtualFiles() {
final List<VirtualFile> files = new ArrayList<VirtualFile>();
for (MavenProjectsStructure.MavenSimpleNode each : getSelectedNodes(MavenProjectsStructure.MavenSimpleNode.class)) {
VirtualFile file = each.getVirtualFile();
if (file != null && file.isValid()) files.add(file);
}
return files.isEmpty() ? null : VfsUtil.toVirtualFileArray(files);
}
private Object extractNavigatables() {
final List<Navigatable> navigatables = new ArrayList<Navigatable>();
for (MavenProjectsStructure.MavenSimpleNode each : getSelectedNodes(MavenProjectsStructure.MavenSimpleNode.class)) {
Navigatable navigatable = each.getNavigatable();
if (navigatable != null) navigatables.add(navigatable);
}
return navigatables.isEmpty() ? null : navigatables.toArray(new Navigatable[navigatables.size()]);
}
private Object extractLocation() {
VirtualFile file = extractVirtualFile();
if (file == null) return null;
List<String> goals = extractGoals(false);
if (goals == null) return null;
PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file);
return psiFile == null ? null : new MavenGoalLocation(myProject, psiFile, goals);
}
@Nullable
private RunnerAndConfigurationSettings extractRunSettings() {
SimpleNode node = myTree.getSelectedNode();
if (!(node instanceof MavenProjectsStructure.RunConfigurationNode)) return null;
return ((MavenProjectsStructure.RunConfigurationNode)node).getSettings();
}
private List<String> extractGoals(boolean qualifiedGoals) {
final MavenProjectsStructure.ProjectNode projectNode = getSelectedProjectNode();
if (projectNode != null) {
MavenProject project = projectNode.getMavenProject();
String goal = project.getDefaultGoal();
if (!StringUtil.isEmptyOrSpaces(goal)) {
// Maven uses StringTokenizer to split defaultGoal. See DefaultLifecycleTaskSegmentCalculator#calculateTaskSegments()
return ContainerUtil.newArrayList(StringUtil.tokenize(new StringTokenizer(goal)));
}
}
else {
final List<MavenProjectsStructure.GoalNode> nodes = getSelectedNodes(MavenProjectsStructure.GoalNode.class);
if (MavenProjectsStructure.getCommonProjectNode(nodes) == null) {
return null;
}
final List<String> goals = new ArrayList<String>();
for (MavenProjectsStructure.GoalNode node : nodes) {
goals.add(qualifiedGoals ? node.getGoal() : node.getName());
}
Collections.sort(goals, myGoalOrderComparator);
return goals;
}
return null;
}
private Object extractProfiles() {
final List<MavenProjectsStructure.ProfileNode> nodes = getSelectedNodes(MavenProjectsStructure.ProfileNode.class);
final Map<String, MavenProfileKind> profiles = new THashMap<String, MavenProfileKind>();
for (MavenProjectsStructure.ProfileNode node : nodes) {
profiles.put(node.getProfileName(), node.getState());
}
return profiles;
}
private Set<MavenArtifact> extractDependencies() {
Set<MavenArtifact> result = new THashSet<MavenArtifact>();
List<MavenProjectsStructure.ProjectNode> projectNodes = getSelectedProjectNodes();
if (!projectNodes.isEmpty()) {
for (MavenProjectsStructure.ProjectNode each : projectNodes) {
result.addAll(each.getMavenProject().getDependencies());
}
return result;
}
List<MavenProjectsStructure.BaseDependenciesNode> nodes = getSelectedNodes(MavenProjectsStructure.BaseDependenciesNode.class);
for (MavenProjectsStructure.BaseDependenciesNode each : nodes) {
if (each instanceof MavenProjectsStructure.DependenciesNode) {
result.addAll(each.getMavenProject().getDependencies());
}
else {
result.add(((MavenProjectsStructure.DependencyNode)each).getArtifact());
}
}
return result;
}
private <T extends MavenProjectsStructure.MavenSimpleNode> List<T> getSelectedNodes(Class<T> aClass) {
return MavenProjectsStructure.getSelectedNodes(myTree, aClass);
}
private List<MavenProjectsStructure.ProjectNode> getSelectedProjectNodes() {
return getSelectedNodes(MavenProjectsStructure.ProjectNode.class);
}
@Nullable
private MavenProjectsStructure.ProjectNode getSelectedProjectNode() {
final List<MavenProjectsStructure.ProjectNode> projectNodes = getSelectedProjectNodes();
return projectNodes.size() == 1 ? projectNodes.get(0) : null;
}
@Nullable
private MavenProjectsStructure.ProjectNode getContextProjectNode() {
MavenProjectsStructure.ProjectNode projectNode = getSelectedProjectNode();
if (projectNode != null) return projectNode;
return MavenProjectsStructure.getCommonProjectNode(getSelectedNodes(MavenProjectsStructure.MavenSimpleNode.class));
}
private static class MyTransferHandler extends TransferHandler {
private final Project myProject;
private MyTransferHandler(Project project) {
myProject = project;
}
@Override
public boolean importData(final TransferSupport support) {
if (canImport(support)) {
List<VirtualFile> pomFiles = new ArrayList<VirtualFile>();
final List<File> fileList = FileCopyPasteUtil.getFileList(support.getTransferable());
if (fileList == null) return false;
MavenProjectsManager manager = MavenProjectsManager.getInstance(myProject);
for (File file : fileList) {
VirtualFile virtualFile = VfsUtil.findFileByIoFile(file, true);
if (file.isFile()
&& virtualFile != null
&& MavenActionUtil.isMavenProjectFile(virtualFile)
&& !manager.isManagedFile(virtualFile)) {
pomFiles.add(virtualFile);
}
}
if (pomFiles.isEmpty()) {
return false;
}
manager.addManagedFilesOrUnignore(pomFiles);
return true;
}
return false;
}
@Override
public boolean canImport(final TransferSupport support) {
return FileCopyPasteUtil.isFileListFlavorAvailable(support.getDataFlavors());
}
}
}