EditorConfig documentation test
[idea/community.git] / java / idea-ui / src / com / intellij / openapi / roots / ui / configuration / projectRoot / LibrariesModifiableModel.java
1 /*
2  * Copyright 2000-2016 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
17 package com.intellij.openapi.roots.ui.configuration.projectRoot;
18
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.roots.ProjectModelExternalSource;
21 import com.intellij.openapi.roots.impl.libraries.LibraryImpl;
22 import com.intellij.openapi.roots.libraries.Library;
23 import com.intellij.openapi.roots.libraries.LibraryTable;
24 import com.intellij.openapi.roots.libraries.PersistentLibraryKind;
25 import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
26 import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor;
27 import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor;
28 import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditorListener;
29 import com.intellij.openapi.util.Disposer;
30 import com.intellij.util.containers.ContainerUtil;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
33
34 import java.util.*;
35
36
37 public class LibrariesModifiableModel implements LibraryTable.ModifiableModel {
38   //todo[nik] remove LibraryImpl#equals method instead of using identity maps
39   private final Map<Library, ExistingLibraryEditor> myLibrary2EditorMap =
40     ContainerUtil.newIdentityTroveMap();
41   private final Set<Library> myRemovedLibraries = ContainerUtil.newIdentityTroveSet();
42
43   private LibraryTable.ModifiableModel myLibrariesModifiableModel;
44   private final Project myProject;
45   private final LibraryTable myTable;
46   private final LibraryEditorListener myLibraryEditorListener;
47
48   public LibrariesModifiableModel(final LibraryTable table, final Project project, LibraryEditorListener libraryEditorListener) {
49     myProject = project;
50     myTable = table;
51     myLibraryEditorListener = libraryEditorListener;
52   }
53
54   @NotNull
55   @Override
56   public Library createLibrary(String name) {
57     return createLibrary(name, null);
58   }
59
60   @NotNull
61   @Override
62   public Library createLibrary(String name, @Nullable PersistentLibraryKind type) {
63     return createLibrary(name, type, null);
64   }
65
66   @NotNull
67   @Override
68   public Library createLibrary(String name, @Nullable PersistentLibraryKind type, @Nullable ProjectModelExternalSource externalSource) {
69     final Library library = getLibrariesModifiableModel().createLibrary(name, type, externalSource);
70     final BaseLibrariesConfigurable configurable = ProjectStructureConfigurable.getInstance(myProject).getConfigurableFor(library);
71     configurable.createLibraryNode(library);
72     return library;
73   }
74
75   @Override
76   public void removeLibrary(@NotNull Library library) {
77     if (getLibrariesModifiableModel().getLibraryByName(library.getName()) == null) return;
78
79     removeLibraryEditor(library);
80     final Library existingLibrary = myTable.getLibraryByName(library.getName());
81     getLibrariesModifiableModel().removeLibrary(library);
82
83     final BaseLibrariesConfigurable configurable = ProjectStructureConfigurable.getInstance(myProject).getConfigurableFor(library);
84     configurable.removeLibraryNode(library);
85
86     if (existingLibrary == library) {
87       myRemovedLibraries.add(library);
88     }
89   }
90
91   @Override
92   public void commit() {
93     //do nothing  - do deffered commit
94   }
95
96   @Override
97   @NotNull
98   public Iterator<Library> getLibraryIterator() {
99     return getLibrariesModifiableModel().getLibraryIterator();
100   }
101
102   @Override
103   public Library getLibraryByName(@NotNull String name) {
104     return getLibrariesModifiableModel().getLibraryByName(name);
105   }
106
107   @Override
108   @NotNull
109   public Library[] getLibraries() {
110     return getLibrariesModifiableModel().getLibraries();
111   }
112
113   @Override
114   public boolean isChanged() {
115     for (LibraryEditor libraryEditor : myLibrary2EditorMap.values()) {
116       if (libraryEditor.hasChanges()) return true;
117     }
118     return getLibrariesModifiableModel().isChanged();
119   }
120
121   public void deferredCommit(){
122     final List<ExistingLibraryEditor> libraryEditors = new ArrayList<>(myLibrary2EditorMap.values());
123     myLibrary2EditorMap.clear();
124     for (ExistingLibraryEditor libraryEditor : libraryEditors) {
125       libraryEditor.commit(); // TODO: is seems like commit will recreate the editor, but it should not
126       Disposer.dispose(libraryEditor);
127     }
128     if (!libraryEditors.isEmpty() || !myRemovedLibraries.isEmpty() || myLibrariesModifiableModel != null && myLibrariesModifiableModel.isChanged()) {
129       getLibrariesModifiableModel().commit();
130       myLibrariesModifiableModel = null;
131     }
132     myRemovedLibraries.clear();
133   }
134
135   public boolean wasLibraryRemoved(Library library){
136     return myRemovedLibraries.contains(library);
137   }
138
139   public boolean hasLibraryEditor(Library library){
140     return myLibrary2EditorMap.containsKey(library);
141   }
142
143   public ExistingLibraryEditor getLibraryEditor(Library library){
144     if (library instanceof LibraryImpl) {
145       final Library source = ((LibraryImpl)library).getSource();
146       if (source != null) {
147         return getLibraryEditor(source);
148       }
149     }
150
151     ExistingLibraryEditor libraryEditor = myLibrary2EditorMap.get(library);
152     if (libraryEditor == null){
153       libraryEditor = createLibraryEditor(library);
154     }
155     return libraryEditor;
156   }
157
158   private ExistingLibraryEditor createLibraryEditor(final Library library) {
159     final ExistingLibraryEditor libraryEditor = new ExistingLibraryEditor(library, myLibraryEditorListener);
160     myLibrary2EditorMap.put(library, libraryEditor);
161     return libraryEditor;
162   }
163
164   private void removeLibraryEditor(final Library library) {
165     final ExistingLibraryEditor libraryEditor = myLibrary2EditorMap.remove(library);
166     if (libraryEditor != null) {
167       Disposer.dispose(libraryEditor);
168     }
169   }
170
171   public Library.ModifiableModel getLibraryModifiableModel(final Library library) {
172     return getLibraryEditor(library).getModel();
173   }
174
175   private LibraryTable.ModifiableModel getLibrariesModifiableModel() {
176     if (myLibrariesModifiableModel == null) {
177       myLibrariesModifiableModel = myTable.getModifiableModel();
178     }
179
180     return myLibrariesModifiableModel;
181   }
182
183   @Override
184   public void dispose() {
185     if (myLibrariesModifiableModel != null) {
186       Disposer.dispose(myLibrariesModifiableModel);
187       myLibrariesModifiableModel = null;
188     }
189     disposeLibraryEditors();
190   }
191
192   private void disposeLibraryEditors() {
193     for (ExistingLibraryEditor libraryEditor : myLibrary2EditorMap.values()) {
194       Disposer.dispose(libraryEditor);
195     }
196     myLibrary2EditorMap.clear();
197   }
198 }