f0181b4fc432a44d0794896ea978a5b1ca722c6b
[idea/community.git] / java / idea-ui / src / com / intellij / openapi / roots / ui / configuration / classpath / AddLibraryDependencyAction.java
1 /*
2  * Copyright 2000-2010 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.roots.ui.configuration.classpath;
17
18 import com.intellij.facet.impl.ProjectFacetsConfigurator;
19 import com.intellij.ide.JavaUiBundle;
20 import com.intellij.openapi.roots.LibraryDependencyScopeSuggester;
21 import com.intellij.openapi.roots.LibraryOrderEntry;
22 import com.intellij.openapi.roots.ModifiableRootModel;
23 import com.intellij.openapi.roots.OrderEntry;
24 import com.intellij.openapi.roots.libraries.Library;
25 import com.intellij.openapi.roots.libraries.LibraryTable;
26 import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil;
27 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel;
28 import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
29 import com.intellij.openapi.ui.Messages;
30 import com.intellij.openapi.ui.popup.PopupStep;
31 import com.intellij.util.PlatformIcons;
32 import com.intellij.util.ui.classpath.ChooseLibrariesFromTablesDialog;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
35
36 import java.util.List;
37 import java.util.function.Predicate;
38
39 class AddLibraryDependencyAction extends AddItemPopupAction<Library> {
40   private final StructureConfigurableContext myContext;
41
42   AddLibraryDependencyAction(ClasspathPanel classpathPanel, final int index, final String title,
43                                     final StructureConfigurableContext context) {
44     super(classpathPanel, index, title, PlatformIcons.LIBRARY_ICON);
45     myContext = context;
46   }
47
48   @Override
49   public boolean hasSubStep() {
50     return !hasLibraries() && LibraryEditingUtil.hasSuitableTypes(myClasspathPanel);
51   }
52
53   @Override
54   public PopupStep createSubStep() {
55     return LibraryEditingUtil.createChooseTypeStep(myClasspathPanel,
56                                                    libraryType -> new AddNewLibraryDependencyAction(myClasspathPanel, myContext, libraryType).execute());
57   }
58
59   @Override
60   public void run() {
61     if (hasLibraries()) {
62       super.run();
63     }
64     else {
65       new AddNewLibraryDependencyAction(myClasspathPanel, myContext, null).run();
66     }
67   }
68
69   private boolean hasLibraries() {
70     final Predicate<Library> condition = getNotAddedSuitableLibrariesCondition();
71     for (LibraryTable table : ChooseLibrariesFromTablesDialog.getLibraryTables(myClasspathPanel.getProject(), true)) {
72       final LibrariesModifiableModel model = myContext.myLevel2Providers.get(table.getTableLevel());
73       if (model != null) {
74         for (Library library : model.getLibraries()) {
75           if (condition.test(library)) {
76             return true;
77           }
78         }
79       }
80     }
81     return false;
82   }
83
84   private java.util.function.Predicate<Library> getNotAddedSuitableLibrariesCondition() {
85     ProjectFacetsConfigurator facetsConfigurator = myContext.getModulesConfigurator().getFacetsConfigurator();
86     return LibraryEditingUtil.getNotAddedSuitableLibrariesCondition(myClasspathPanel.getRootModel(), facetsConfigurator);
87   }
88
89   @Override
90   @Nullable
91   protected ClasspathTableItem<?> createTableItem(final Library item) {
92     // clear invalid order entry corresponding to added library if any
93     final ModifiableRootModel rootModel = myClasspathPanel.getRootModel();
94     final OrderEntry[] orderEntries = rootModel.getOrderEntries();
95     for (OrderEntry orderEntry : orderEntries) {
96       if (orderEntry instanceof LibraryOrderEntry) {
97         final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry;
98         if (item.equals(libraryOrderEntry.getLibrary())) {
99           return ClasspathTableItem.createLibItem(libraryOrderEntry, myContext);
100         }
101         String name = item.getName();
102         if (name != null && name.equals(libraryOrderEntry.getLibraryName())) {
103           if (orderEntry.isValid()) {
104             Messages.showErrorDialog(JavaUiBundle.message("classpath.message.library.already.added", item.getName()),
105                                      JavaUiBundle.message("classpath.title.adding.dependency"));
106             return null;
107           }
108           else {
109             rootModel.removeOrderEntry(orderEntry);
110           }
111         }
112       }
113     }
114     final LibraryOrderEntry orderEntry = rootModel.addLibraryEntry(item);
115     orderEntry.setScope(LibraryDependencyScopeSuggester.getDefaultScope(item));
116     return ClasspathTableItem.createLibItem(orderEntry, myContext);
117   }
118
119   @Override
120   protected ClasspathElementChooser<Library> createChooser() {
121     return new ExistingLibraryChooser();
122   }
123
124   class ExistingLibraryChooser implements ClasspathElementChooser<Library> {
125     @Override
126     @NotNull
127     public List<Library> chooseElements() {
128       ProjectStructureChooseLibrariesDialog dialog = new ProjectStructureChooseLibrariesDialog(myClasspathPanel, myContext,
129                                                                                                getNotAddedSuitableLibrariesCondition());
130       dialog.show();
131       return dialog.getSelectedLibraries();
132     }
133   }
134 }