[project-model] findModuleForPsiElement: check original file if PsiFile is supplied
[idea/community.git] / java / idea-ui / src / com / intellij / openapi / roots / ui / configuration / libraryEditor / CreateNewLibraryAction.java
1 // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.openapi.roots.ui.configuration.libraryEditor;
3
4 import com.intellij.ide.JavaUiBundle;
5 import com.intellij.openapi.actionSystem.AnAction;
6 import com.intellij.openapi.actionSystem.AnActionEvent;
7 import com.intellij.openapi.application.WriteAction;
8 import com.intellij.openapi.project.DumbAwareAction;
9 import com.intellij.openapi.project.Project;
10 import com.intellij.openapi.roots.impl.libraries.LibraryEx;
11 import com.intellij.openapi.roots.libraries.Library;
12 import com.intellij.openapi.roots.libraries.LibraryType;
13 import com.intellij.openapi.roots.libraries.LibraryTypeService;
14 import com.intellij.openapi.roots.libraries.NewLibraryConfiguration;
15 import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
16 import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil;
17 import com.intellij.openapi.roots.ui.configuration.projectRoot.BaseLibrariesConfigurable;
18 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel;
19 import com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable;
20 import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectLibrariesConfigurable;
21 import com.intellij.openapi.ui.MasterDetailsComponent;
22 import com.intellij.openapi.util.NlsActions;
23 import com.intellij.openapi.vfs.VirtualFile;
24 import com.intellij.util.PlatformIcons;
25 import org.jetbrains.annotations.NotNull;
26 import org.jetbrains.annotations.Nullable;
27
28 import javax.swing.*;
29 import javax.swing.tree.DefaultMutableTreeNode;
30 import javax.swing.tree.TreeNode;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.List;
34
35 public final class CreateNewLibraryAction extends DumbAwareAction {
36   private final @Nullable LibraryType myType;
37   private final BaseLibrariesConfigurable myLibrariesConfigurable;
38   private final Project myProject;
39
40   private CreateNewLibraryAction(@NotNull @NlsActions.ActionText String text,
41                                  @Nullable Icon icon,
42                                  @Nullable LibraryType type,
43                                  @NotNull BaseLibrariesConfigurable librariesConfigurable,
44                                  final @NotNull Project project) {
45     super(text, null, icon);
46     myType = type;
47     myLibrariesConfigurable = librariesConfigurable;
48     myProject = project;
49   }
50
51   @Nullable
52   public static Library createLibrary(@Nullable final LibraryType type, @NotNull final JComponent parentComponent,
53                                       @NotNull final Project project, @NotNull final LibrariesModifiableModel modifiableModel) {
54     final NewLibraryConfiguration configuration = createNewLibraryConfiguration(type, parentComponent, project);
55     if (configuration == null) return null;
56     final LibraryType<?> libraryType = configuration.getLibraryType();
57     final Library library = modifiableModel.createLibrary(
58       LibraryEditingUtil.suggestNewLibraryName(modifiableModel, configuration.getDefaultLibraryName()),
59       libraryType != null ? libraryType.getKind() : null);
60
61     final NewLibraryEditor editor = new NewLibraryEditor(libraryType, configuration.getProperties());
62     configuration.addRoots(editor);
63     final Library.ModifiableModel model = library.getModifiableModel();
64     editor.applyTo((LibraryEx.ModifiableModelEx)model);
65     WriteAction.run(() -> model.commit());
66     return library;
67   }
68
69   @Nullable
70   public static NewLibraryConfiguration createNewLibraryConfiguration(@Nullable LibraryType type, @NotNull JComponent parentComponent, @NotNull Project project) {
71     final NewLibraryConfiguration configuration;
72     final VirtualFile baseDir = project.getBaseDir();
73     if (type != null) {
74       configuration = type.createNewLibrary(parentComponent, baseDir, project);
75     }
76     else {
77       configuration = LibraryTypeService
78         .getInstance().createLibraryFromFiles(new DefaultLibraryRootsComponentDescriptor(), parentComponent, baseDir, null, project);
79     }
80     if (configuration == null) return null;
81     return configuration;
82   }
83
84   public static AnAction[] createActionOrGroup(@NotNull @NlsActions.ActionText String text,
85                                                @NotNull BaseLibrariesConfigurable librariesConfigurable,
86                                                final @NotNull Project project) {
87     final LibraryType<?>[] extensions = LibraryType.EP_NAME.getExtensions();
88     List<LibraryType<?>> suitableTypes = new ArrayList<>();
89     if (librariesConfigurable instanceof ProjectLibrariesConfigurable || !project.isDefault()) {
90       final ModuleStructureConfigurable configurable = ModuleStructureConfigurable.getInstance(project);
91       for (LibraryType<?> extension : extensions) {
92         if (!LibraryEditingUtil.getSuitableModules(configurable, extension.getKind(), null).isEmpty()) {
93           suitableTypes.add(extension);
94         }
95       }
96     }
97     else {
98       Collections.addAll(suitableTypes, extensions);
99     }
100
101     if (suitableTypes.isEmpty()) {
102       return new AnAction[]{new CreateNewLibraryAction(text, PlatformIcons.LIBRARY_ICON, null, librariesConfigurable, project)};
103     }
104     List<AnAction> actions = new ArrayList<>();
105     actions.add(new CreateNewLibraryAction(JavaUiBundle.message("create.default.library.type.action.name"), PlatformIcons.LIBRARY_ICON, null, librariesConfigurable, project));
106     for (LibraryType<?> type : suitableTypes) {
107       final String actionName = type.getCreateActionName();
108       if (actionName != null) {
109         actions.add(new CreateNewLibraryAction(actionName, type.getIcon(null), type, librariesConfigurable, project));
110       }
111     }
112     return actions.toArray(AnAction.EMPTY_ARRAY);
113   }
114
115   @Override
116   public void actionPerformed(@NotNull AnActionEvent e) {
117     Library library =
118       createLibrary(myType, myLibrariesConfigurable.getTree(), myProject, myLibrariesConfigurable.getModelProvider().getModifiableModel());
119     if (library == null) return;
120
121     final BaseLibrariesConfigurable rootConfigurable = ProjectStructureConfigurable.getInstance(myProject).getConfigurableFor(library);
122     final DefaultMutableTreeNode
123       libraryNode = MasterDetailsComponent.findNodeByObject((TreeNode)rootConfigurable.getTree().getModel().getRoot(), library);
124     rootConfigurable.selectNodeInTree(libraryNode);
125     LibraryEditingUtil.showDialogAndAddLibraryToDependencies(library, myProject, true);
126   }
127 }