ModuleRootManagerComponent — increment serialization modification count on project library change (if used)

This commit is contained in:
Vladimir Krivosheev
2016-12-28 17:48:59 +01:00
parent c85eb97bbd
commit f10f69dd9b
3 changed files with 50 additions and 7 deletions
@@ -22,8 +22,10 @@ import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.NativeLibraryOrderRootType;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.impl.ModuleRootManagerComponent;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.impl.libraries.LibraryTableBase;
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
@@ -40,6 +42,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import static com.intellij.testFramework.assertions.Assertions.assertThat;
/**
* @author dsl
*/
@@ -71,8 +75,11 @@ public class LibraryTest extends ModuleRootManagerTestCase {
}
public void testLibrarySerialization() {
final long moduleModificationCount = ((ModuleRootManagerComponent)ModuleRootManager.getInstance(myModule)).getStateModificationCount();
Library library = PsiTestUtil.addProjectLibrary(myModule, "junit", Collections.singletonList(getJDomJar()),
Collections.singletonList(getJDomSources()));
assertThat(((ModuleRootManagerComponent)ModuleRootManager.getInstance(myModule)).getStateModificationCount()).isGreaterThan(moduleModificationCount);
Element element = serialize(library);
String classesUrl = getJDomJar().getUrl();
String sourcesUrl = getJDomSources().getUrl();
@@ -93,14 +100,21 @@ public class LibraryTest extends ModuleRootManagerTestCase {
}
public void testFindLibraryByNameAfterRename() {
final long moduleModificationCount = ((ModuleRootManagerComponent)ModuleRootManager.getInstance(myModule)).getStateModificationCount();
ProjectLibraryTable table = (ProjectLibraryTable)getLibraryTable();
final long projectLibraryModificationCount = table.getStateModificationCount();
Library a = createLibrary("a", null, null);
LibraryTable table = getLibraryTable();
LibraryTable.ModifiableModel model = table.getModifiableModel();
assertSame(a, table.getLibraryByName("a"));
assertSame(a, model.getLibraryByName("a"));
Library.ModifiableModel libraryModel = a.getModifiableModel();
libraryModel.setName("b");
commit(libraryModel);
// module not marked as to save if project library modified, but module is not affected
assertThat(((ModuleRootManagerComponent)ModuleRootManager.getInstance(myModule)).getStateModificationCount()).isEqualTo(moduleModificationCount);
assertThat(table.getStateModificationCount()).isGreaterThan(projectLibraryModificationCount);
assertNull(table.getLibraryByName("a"));
assertNull(model.getLibraryByName("a"));
assertSame(a, table.getLibraryByName("b"));
@@ -20,9 +20,13 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.impl.ModuleEx;
import com.intellij.openapi.roots.impl.storage.ClassPathStorageUtil;
import com.intellij.openapi.roots.impl.storage.ClasspathStorage;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author yole
*/
@@ -58,11 +62,22 @@ public class ModuleRootManagerComponent extends ModuleRootManagerImpl implements
@Override
public long getStateModificationCount() {
long result = myModificationCount;
Module module = getModule();
if (module instanceof ModuleEx) {
result += ((ModuleEx)module).getOptionsModificationCount();
if (!module.isLoaded() || !(module instanceof ModuleEx)) {
return myModificationCount;
}
return result;
final long[] result = {myModificationCount};
result[0] += ((ModuleEx)module).getOptionsModificationCount();
final List<String> handledLibraryTables = new SmartList<>();
getRootModel().orderEntries().forEachLibrary(library -> {
LibraryTable table = library.getTable();
if (table instanceof PersistentStateComponentWithModificationTracker && !handledLibraryTables.contains(table.getTableLevel())) {
handledLibraryTables.add(table.getTableLevel());
result[0] += ((PersistentStateComponentWithModificationTracker)table).getStateModificationCount();
}
return true;
});
return result[0];
}
}
@@ -19,7 +19,7 @@ package com.intellij.openapi.roots.impl.libraries;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.PersistentStateComponentWithModificationTracker;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
@@ -40,12 +40,14 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public abstract class LibraryTableBase implements PersistentStateComponent<Element>, LibraryTable, Disposable {
public abstract class LibraryTableBase implements PersistentStateComponentWithModificationTracker<Element>, LibraryTable, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.libraries.LibraryTableBase");
private final EventDispatcher<Listener> myDispatcher = EventDispatcher.create(Listener.class);
private LibraryModel myModel = new LibraryModel();
private boolean myFirstLoad = true;
private volatile long myModificationCount;
@NotNull
@Override
public ModifiableModel getModifiableModel() {
@@ -85,6 +87,11 @@ public abstract class LibraryTableBase implements PersistentStateComponent<Eleme
}
}
@Override
public long getStateModificationCount() {
return myModificationCount;
}
@Override
@NotNull
public Library[] getLibraries() {
@@ -118,6 +125,7 @@ public abstract class LibraryTableBase implements PersistentStateComponent<Eleme
}
private void fireLibraryAdded (Library library) {
myModificationCount++;
if (LOG.isDebugEnabled()) {
LOG.debug("fireLibraryAdded: " + library);
}
@@ -125,6 +133,7 @@ public abstract class LibraryTableBase implements PersistentStateComponent<Eleme
}
private void fireBeforeLibraryRemoved (Library library) {
myModificationCount++;
if (LOG.isDebugEnabled()) {
LOG.debug("fireBeforeLibraryRemoved: " + library);
}
@@ -145,6 +154,7 @@ public abstract class LibraryTableBase implements PersistentStateComponent<Eleme
}
public void fireLibraryRenamed(@NotNull LibraryImpl library) {
myModificationCount++;
myDispatcher.getMulticaster().afterLibraryRenamed(library);
}
@@ -170,6 +180,8 @@ public abstract class LibraryTableBase implements PersistentStateComponent<Eleme
Disposer.dispose(model);
return;
}
myModificationCount++;
//todo[nik] remove LibraryImpl#equals method instead of using identity sets
Set<Library> addedLibraries = ContainerUtil.newIdentityTroveSet(model.myLibraries);
addedLibraries.removeAll(myModel.myLibraries);
@@ -290,6 +302,8 @@ public abstract class LibraryTableBase implements PersistentStateComponent<Eleme
@Override
public void removeLibrary(@NotNull Library library) {
myModificationCount++;
assertWritable();
myLibraries.remove(library);
myLibraryByNameCache = null;