revert LibraryTableBase changes to fix tests, will investigate l8r
[fedora-idea.git] / platform / lang-impl / src / com / intellij / openapi / roots / impl / libraries / LibraryTableBase.java
blobeae14c47037f5fc8debf270422dbef2bccc148bf
1 package com.intellij.openapi.roots.impl.libraries;
3 import com.intellij.openapi.Disposable;
4 import com.intellij.openapi.application.ApplicationManager;
5 import com.intellij.openapi.components.PersistentStateComponent;
6 import com.intellij.openapi.diagnostic.Logger;
7 import com.intellij.openapi.roots.OrderRootType;
8 import com.intellij.openapi.roots.libraries.Library;
9 import com.intellij.openapi.roots.libraries.LibraryTable;
10 import com.intellij.openapi.util.*;
11 import com.intellij.util.EventDispatcher;
12 import com.intellij.util.containers.HashSet;
13 import org.jdom.Element;
14 import org.jetbrains.annotations.NonNls;
15 import org.jetbrains.annotations.NotNull;
16 import org.jetbrains.annotations.Nullable;
18 import java.util.*;
20 public abstract class LibraryTableBase implements PersistentStateComponent<Element>, LibraryTable, Disposable {
21 private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.libraries.LibraryTableBase");
22 private final EventDispatcher<Listener> myDispatcher = EventDispatcher.create(Listener.class);
23 private LibraryModel myModel = new LibraryModel();
24 private boolean myFirstLoad = true;
26 public ModifiableModel getModifiableModel() {
27 return new LibraryModel(myModel);
30 public Element getState() {
31 final Element element = new Element("state");
32 try {
33 myModel.writeExternal(element);
35 catch (WriteExternalException e) {
36 LOG.error(e);
38 return element;
41 public void loadState(final Element element) {
42 try {
43 if (myFirstLoad) {
44 myModel.readExternal(element);
46 else {
47 final LibraryModel model = new LibraryModel();
48 model.readExternal(element);
49 commit(model);
52 myFirstLoad = false;
54 catch (InvalidDataException e) {
55 throw new RuntimeException(e);
59 @NotNull
60 public Library[] getLibraries() {
61 return myModel.getLibraries();
64 @NotNull
65 public Iterator<Library> getLibraryIterator() {
66 return myModel.getLibraryIterator();
69 public Library getLibraryByName(@NotNull String name) {
70 return myModel.getLibraryByName(name);
73 public void addListener(Listener listener) {
74 myDispatcher.addListener(listener);
77 public void addListener(Listener listener, Disposable parentDisposable) {
78 myDispatcher.addListener(listener, parentDisposable);
81 public void removeListener(Listener listener) {
82 myDispatcher.removeListener(listener);
85 private void fireLibraryAdded (Library library) {
86 if (LOG.isDebugEnabled()) {
87 LOG.debug("fireLibraryAdded: " + library);
89 myDispatcher.getMulticaster().afterLibraryAdded(library);
92 private void fireBeforeLibraryRemoved (Library library) {
93 if (LOG.isDebugEnabled()) {
94 LOG.debug("fireBeforeLibraryRemoved: " + library);
96 myDispatcher.getMulticaster().beforeLibraryRemoved(library);
99 public void dispose() {
100 for (Library library : getLibraries()) {
101 Disposer.dispose(library);
105 public Library createLibrary() {
106 ApplicationManager.getApplication().assertWriteAccessAllowed();
107 return createLibrary(null);
110 public void fireLibraryRenamed(LibraryImpl library) {
111 myDispatcher.getMulticaster().afterLibraryRenamed(library);
114 public Library createLibrary(String name) {
115 final ModifiableModel modifiableModel = getModifiableModel();
116 final Library library = modifiableModel.createLibrary(name);
117 modifiableModel.commit();
118 return library;
121 public void removeLibrary(@NotNull Library library) {
122 final ModifiableModel modifiableModel = getModifiableModel();
123 modifiableModel.removeLibrary(library);
124 modifiableModel.commit();
127 private void commit(LibraryModel model) {
128 ApplicationManager.getApplication().assertWriteAccessAllowed();
129 List<Library> addedLibraries = new ArrayList<Library>(model.myLibraries);
130 addedLibraries.removeAll(myModel.myLibraries);
131 List<Library> removedLibraries = new ArrayList<Library>(myModel.myLibraries);
132 removedLibraries.removeAll(model.myLibraries);
134 for (Library library : removedLibraries) {
135 fireBeforeLibraryRemoved(library);
138 // dispose newly created instances of same (equals()) libraries
139 //for (final Library library : model.myLibraries) {
140 // if (addedLibraries.contains(library)) continue;
141 // for (final Library oldLibrary : myModel.myLibraries) {
142 // if (library.equals(oldLibrary) && library != oldLibrary) {
143 // final int index = model.myLibraries.indexOf(library);
144 // Disposer.dispose(library);
146 // // keep old library if somebody cached old instance
147 // model.myLibraries.set(index, oldLibrary);
148 // break;
149 // }
150 // }
153 myModel = model;
154 for (Library library : removedLibraries) {
155 Disposer.dispose(library);
156 fireAfterLibraryRemoved(library);
158 for (Library library : addedLibraries) {
159 fireLibraryAdded(library);
163 private void fireAfterLibraryRemoved(Library library) {
164 myDispatcher.getMulticaster().afterLibraryRemoved(library);
167 public void readExternal(final Element element) throws InvalidDataException {
168 myModel = new LibraryModel();
169 myModel.readExternal(element);
172 public void writeExternal(final Element element) throws WriteExternalException {
173 myModel.writeExternal(element);
176 public class LibraryModel implements ModifiableModel, JDOMExternalizable {
177 private final ArrayList<Library> myLibraries = new ArrayList<Library>();
178 private boolean myWritable;
180 private LibraryModel() {
181 myWritable = false;
184 private LibraryModel(LibraryModel that) {
185 myWritable = true;
186 myLibraries.addAll(that.myLibraries);
189 public void commit() {
190 myWritable = false;
191 LibraryTableBase.this.commit(this);
194 @NotNull
195 public Iterator<Library> getLibraryIterator() {
196 return Collections.unmodifiableList(myLibraries).iterator();
199 @Nullable
200 public Library getLibraryByName(@NotNull String name) {
201 for (Library myLibrary : myLibraries) {
202 LibraryImpl library = (LibraryImpl)myLibrary;
203 if (Comparing.equal(name, library.getName())) return library;
205 @NonNls final String libraryPrefix = "library.";
206 final String libPath = System.getProperty(libraryPrefix + name);
207 if (libPath != null) {
208 final LibraryImpl library = new LibraryImpl(name, LibraryTableBase.this, null);
209 library.addRoot(libPath, OrderRootType.CLASSES);
210 return library;
212 return null;
216 @NotNull
217 public Library[] getLibraries() {
218 return myLibraries.toArray(new Library[myLibraries.size()]);
221 private void assertWritable() {
222 LOG.assertTrue(myWritable);
225 public Library createLibrary(String name) {
226 assertWritable();
227 final LibraryImpl library = new LibraryImpl(name, LibraryTableBase.this, null);
228 myLibraries.add(library);
229 return library;
232 public void removeLibrary(@NotNull Library library) {
233 assertWritable();
234 myLibraries.remove(library);
237 public boolean isChanged() {
238 if (!myWritable) return false;
239 Set<Library> thisLibraries = new HashSet<Library>(myLibraries);
240 Set<Library> thatLibraries = new HashSet<Library>(myModel.myLibraries);
241 return !thisLibraries.equals(thatLibraries);
244 public void readExternal(Element element) throws InvalidDataException {
245 HashMap<String, Library> libraries = new HashMap<String, Library>();
246 for (Library library : myLibraries) {
247 libraries.put(library.getName(), library);
250 final List libraryElements = element.getChildren(LibraryImpl.ELEMENT);
251 for (Object libraryElement1 : libraryElements) {
252 Element libraryElement = (Element)libraryElement1;
253 final LibraryImpl library = new LibraryImpl(LibraryTableBase.this, libraryElement, null);
254 if (library.getName() != null) {
255 Library oldLibrary = libraries.get(library.getName());
256 if (oldLibrary != null) {
257 removeLibrary(oldLibrary);
260 myLibraries.add(library);
261 fireLibraryAdded(library);
266 public void writeExternal(Element element) throws WriteExternalException {
267 for (Library library : myLibraries) {
268 if (library.getName() != null) {
269 library.writeExternal(element);