merged 'add existing library' and 'add new library' actions in classpath editor
[idea/community.git] / java / idea-ui / src / com / intellij / openapi / roots / ui / configuration / classpath / AddLibraryAction.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.openapi.project.ProjectBundle;
19 import com.intellij.openapi.roots.LibraryOrderEntry;
20 import com.intellij.openapi.roots.ModifiableRootModel;
21 import com.intellij.openapi.roots.OrderEntry;
22 import com.intellij.openapi.roots.impl.libraries.LibraryImpl;
23 import com.intellij.openapi.roots.libraries.Library;
24 import com.intellij.openapi.roots.libraries.LibraryTable;
25 import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
26 import com.intellij.openapi.ui.Messages;
27 import com.intellij.openapi.util.Condition;
28 import com.intellij.util.Icons;
29 import com.intellij.util.ui.classpath.ChooseLibrariesFromTablesDialog;
30 import org.jetbrains.annotations.Nullable;
31
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Set;
35
36 /**
37 * @author nik
38 */
39 class AddLibraryAction extends AddItemPopupAction<Library> {
40   private StructureConfigurableContext myContext;
41   private AddNewLibraryItemAction myNewLibraryAction;
42
43   public AddLibraryAction(ClasspathPanel classpathPanel, final int index, final String title,
44                           final StructureConfigurableContext context) {
45     super(classpathPanel, index, title, Icons.LIBRARY_ICON);
46     myContext = context;
47     myNewLibraryAction = new AddNewLibraryItemAction(classpathPanel, context);
48   }
49
50   @Override
51   public void run() {
52     if (hasLibraries()) {
53       super.run();
54     }
55     else {
56       myNewLibraryAction.run();
57     }
58   }
59
60   private boolean hasLibraries() {
61     final Condition<Library> condition = getNotAddedLibrariesCondition();
62     for (LibraryTable table : ChooseLibrariesFromTablesDialog.getLibraryTables(myClasspathPanel.getProject(), true)) {
63       for (Library library : table.getLibraries()) {
64         if (condition.value(library)) {
65           return true;
66         }
67       }
68     }
69     return false;
70   }
71
72   @Nullable
73   protected ClasspathTableItem createTableItem(final Library item) {
74     // clear invalid order entry corresponding to added library if any
75     final ModifiableRootModel rootModel = myClasspathPanel.getRootModel();
76     final OrderEntry[] orderEntries = rootModel.getOrderEntries();
77     for (OrderEntry orderEntry : orderEntries) {
78       if (orderEntry instanceof LibraryOrderEntry) {
79         if (item.getName().equals(((LibraryOrderEntry)orderEntry).getLibraryName())) {
80           if (orderEntry.isValid()) {
81             Messages.showErrorDialog(ProjectBundle.message("classpath.message.library.already.added",item.getName()),
82                                      ProjectBundle.message("classpath.title.adding.dependency"));
83             return null;
84           } else {
85             rootModel.removeOrderEntry(orderEntry);
86           }
87         }
88       }
89     }
90     return ClasspathTableItem.createLibItem(rootModel.addLibraryEntry(item));
91   }
92
93   protected ClasspathElementChooser<Library> createChooser() {
94     return new ExistingLibraryChooser();
95   }
96
97   private Condition<Library> getNotAddedLibrariesCondition() {
98     final OrderEntry[] orderEntries = myClasspathPanel.getRootModel().getOrderEntries();
99     final Set<Library> result = new HashSet<Library>(orderEntries.length);
100     for (OrderEntry orderEntry : orderEntries) {
101       if (orderEntry instanceof LibraryOrderEntry && orderEntry.isValid()) {
102         final LibraryImpl library = (LibraryImpl)((LibraryOrderEntry)orderEntry).getLibrary();
103         if (library != null) {
104           final Library source = library.getSource();
105           result.add(source != null ? source : library);
106         }
107       }
108     }
109     return new Condition<Library>() {
110       @Override
111       public boolean value(Library library) {
112         if (result.contains(library)) return false;
113         if (library instanceof LibraryImpl) {
114           final Library source = ((LibraryImpl)library).getSource();
115           if (source != null && result.contains(source)) return false;
116         }
117         return true;
118       }
119     };
120   }
121
122   class ExistingLibraryChooser implements ClasspathElementChooser<Library> {
123     private List<Library> mySelectedLibraries;
124
125     public List<Library> getChosenElements() {
126       return mySelectedLibraries;
127     }
128
129     public void doChoose() {
130       ProjectStructureChooseLibrariesDialog dialog = new ProjectStructureChooseLibrariesDialog(myClasspathPanel.getComponent(), myClasspathPanel.getProject(), myContext,
131                                                                                                getNotAddedLibrariesCondition(), myNewLibraryAction);
132       dialog.show();
133       mySelectedLibraries = dialog.getSelectedLibraries();
134     }
135
136     public boolean isOK() {
137       return mySelectedLibraries != null && !mySelectedLibraries.isEmpty();
138     }
139
140     public void dispose() {
141     }
142   }
143 }