mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
VirtualFilePointer validity events on bus solves missing listener problem.
This commit is contained in:
+48
-17
@@ -62,6 +62,7 @@ import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -79,8 +80,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
|
||||
private final EventDispatcher<ProjectJdkListener> myProjectJdkEventDispatcher = EventDispatcher.create(ProjectJdkListener.class);
|
||||
|
||||
private final MyVirtualFilePointerListener myVirtualFilePointerListener = new MyVirtualFilePointerListener();
|
||||
|
||||
private AppListener myApplicationListener;
|
||||
|
||||
private String myProjectJdkName;
|
||||
@@ -102,7 +101,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
private final MessageBusConnection myConnection;
|
||||
private final VirtualFileManagerAdapter myVFSListener;
|
||||
private final BatchUpdateListener myHandler;
|
||||
private final StartupManager myStartupManager;
|
||||
|
||||
private class BatchSession {
|
||||
private int myBatchLevel = 0;
|
||||
@@ -175,7 +173,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
FileTypeManager fileTypeManager,
|
||||
DirectoryIndex directoryIndex,
|
||||
StartupManager startupManager) {
|
||||
myStartupManager = startupManager;
|
||||
myProject = (ProjectEx)project;
|
||||
myConnection = project.getMessageBus().connect();
|
||||
myConnection.subscribe(AppTopics.FILE_TYPES, new FileTypeListener() {
|
||||
@@ -215,6 +212,8 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
myFileTypesChanged.levelDown();
|
||||
}
|
||||
};
|
||||
|
||||
myConnection.subscribe(VirtualFilePointerListener.TOPIC, new MyVirtualFilePointerListener());
|
||||
}
|
||||
|
||||
public void registerRootsChangeUpdater(CacheUpdater updater) {
|
||||
@@ -246,7 +245,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
}
|
||||
|
||||
public VirtualFilePointerListener getVirtualFilePointerListener() {
|
||||
return myVirtualFilePointerListener;
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -629,9 +628,20 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
}
|
||||
|
||||
private void addRootsToWatch() {
|
||||
if (myProject.isDefault()) {
|
||||
return;
|
||||
}
|
||||
final Set<String> rootPaths = getAllRoots();
|
||||
if (rootPaths == null) return;
|
||||
|
||||
final Set<LocalFileSystem.WatchRequest> newRootsToWatch = LocalFileSystem.getInstance().addRootsToWatch(rootPaths, true);
|
||||
|
||||
//remove old requests after adding new ones, helps avoiding unnecessary synchronizations
|
||||
LocalFileSystem.getInstance().removeWatchedRoots(myRootsToWatch);
|
||||
myRootsToWatch = newRootsToWatch;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Set<String> getAllRoots() {
|
||||
if (myProject.isDefault()) return null;
|
||||
|
||||
final Set<String> rootPaths = new HashSet<String>();
|
||||
Module[] modules = ModuleManager.getInstance(myProject).getModules();
|
||||
for (Module module : modules) {
|
||||
@@ -679,11 +689,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
}
|
||||
}
|
||||
|
||||
final Set<LocalFileSystem.WatchRequest> newRootsToWatch = LocalFileSystem.getInstance().addRootsToWatch(rootPaths, true);
|
||||
|
||||
//remove old requests after adding new ones, helps avoiding unnecessary synchronizations
|
||||
LocalFileSystem.getInstance().removeWatchedRoots(myRootsToWatch);
|
||||
myRootsToWatch = newRootsToWatch;
|
||||
return rootPaths;
|
||||
}
|
||||
|
||||
private static Collection<String> getRootsToTrack(final Library library, final OrderRootType rootType) {
|
||||
@@ -740,12 +746,16 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
public void beforeValidityChanged(VirtualFilePointer[] pointers) {
|
||||
if (!myProject.isDisposed()) {
|
||||
if (myInsideRefresh == 0) {
|
||||
beforeRootsChange(false);
|
||||
if (affectsRoots(pointers)) {
|
||||
beforeRootsChange(false);
|
||||
}
|
||||
}
|
||||
else if (!myPointerChangesDetected) {
|
||||
//this is the first pointer changing validity
|
||||
myPointerChangesDetected = true;
|
||||
myProject.getMessageBus().syncPublisher(ProjectTopics.PROJECT_ROOTS).beforeRootsChange(new ModuleRootEventImpl(myProject, false));
|
||||
if (affectsRoots(pointers)) {
|
||||
myPointerChangesDetected = true;
|
||||
myProject.getMessageBus().syncPublisher(ProjectTopics.PROJECT_ROOTS).beforeRootsChange(new ModuleRootEventImpl(myProject, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -756,12 +766,33 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
clearScopesCaches();
|
||||
}
|
||||
else {
|
||||
rootsChanged(false);
|
||||
if (affectsRoots(pointers)) {
|
||||
rootsChanged(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean affectsRoots(VirtualFilePointer[] pointers) {
|
||||
Set<String> roots = getAllRoots();
|
||||
if (roots == null) return false;
|
||||
|
||||
for (VirtualFilePointer pointer : pointers) {
|
||||
if (roots.contains(url2path(pointer.getUrl()))) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String url2path(String url) {
|
||||
String path = VfsUtil.urlToPath(url);
|
||||
|
||||
int separatorIndex = path.indexOf(JarFileSystem.JAR_SEPARATOR);
|
||||
if (separatorIndex < 0) return path;
|
||||
return path.substring(0, separatorIndex);
|
||||
}
|
||||
|
||||
private int myInsideRefresh = 0;
|
||||
private boolean myPointerChangesDetected = false;
|
||||
|
||||
|
||||
+4
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
package com.intellij.openapi.vfs.pointers;
|
||||
|
||||
import com.intellij.util.messages.Topic;
|
||||
|
||||
public interface VirtualFilePointerListener {
|
||||
Topic<VirtualFilePointerListener> TOPIC = Topic.create("VirtualFilePointer", VirtualFilePointerListener.class);
|
||||
|
||||
void beforeValidityChanged(VirtualFilePointer[] pointers);
|
||||
void validityChanged(VirtualFilePointer[] pointers);
|
||||
}
|
||||
|
||||
+20
-8
@@ -50,6 +50,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
|
||||
// guarded by myContainers
|
||||
private final Set<VirtualFilePointerContainerImpl> myContainers = new THashSet<VirtualFilePointerContainerImpl>(TObjectHashingStrategy.IDENTITY);
|
||||
private final VirtualFileManagerEx myVirtualFileManager;
|
||||
private MessageBus myBus;
|
||||
private static final Comparator<String> COMPARATOR = SystemInfo.isFileSystemCaseSensitive ? new Comparator<String>() {
|
||||
public int compare(@NotNull String url1, @NotNull String url2) {
|
||||
return url1.compareTo(url2);
|
||||
@@ -62,6 +63,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
|
||||
|
||||
VirtualFilePointerManagerImpl(@NotNull VirtualFileManagerEx virtualFileManagerEx, MessageBus bus) {
|
||||
myVirtualFileManager = virtualFileManagerEx;
|
||||
myBus = bus;
|
||||
bus.connect().subscribe(VirtualFileManager.VFS_CHANGES, new VFSEventsProcessor());
|
||||
}
|
||||
|
||||
@@ -102,12 +104,12 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
|
||||
}
|
||||
}
|
||||
|
||||
private List<VirtualFilePointer> getPointersUnder(String path) {
|
||||
private List<VirtualFilePointer> getPointersUnder(String path, boolean allowSameFSOptimization) {
|
||||
final List<VirtualFilePointer> pointers = new ArrayList<VirtualFilePointer>();
|
||||
final boolean urlFromJarFS = path.indexOf(JarFileSystem.JAR_SEPARATOR) > 0;
|
||||
final boolean urlFromJarFS = allowSameFSOptimization && path.indexOf(JarFileSystem.JAR_SEPARATOR) > 0;
|
||||
for (TreeMap<String, VirtualFilePointerImpl> urlToPointer : myUrlToPointerMaps.values()) {
|
||||
for (String pointerUrl : urlToPointer.keySet()) {
|
||||
final boolean pointerFromJarFS = pointerUrl.indexOf(JarFileSystem.JAR_SEPARATOR) > 0;
|
||||
final boolean pointerFromJarFS = allowSameFSOptimization && pointerUrl.indexOf(JarFileSystem.JAR_SEPARATOR) > 0;
|
||||
if (urlFromJarFS != pointerFromJarFS) {
|
||||
continue; // optimization: consider pointers from the same FS as the url specified
|
||||
}
|
||||
@@ -440,21 +442,21 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
|
||||
if (event instanceof VFileDeleteEvent) {
|
||||
final VFileDeleteEvent deleteEvent = (VFileDeleteEvent)event;
|
||||
String url = deleteEvent.getFile().getPath();
|
||||
toFireEvents.addAll(getPointersUnder(url));
|
||||
toFireEvents.addAll(getPointersUnder(url, true));
|
||||
}
|
||||
else if (event instanceof VFileCreateEvent) {
|
||||
final VFileCreateEvent createEvent = (VFileCreateEvent)event;
|
||||
String url = createEvent.getPath();
|
||||
toFireEvents.addAll(getPointersUnder(url));
|
||||
toFireEvents.addAll(getPointersUnder(url, false));
|
||||
}
|
||||
else if (event instanceof VFileCopyEvent) {
|
||||
final VFileCopyEvent copyEvent = (VFileCopyEvent)event;
|
||||
String url = copyEvent.getNewParent().getPath() + "/" + copyEvent.getFile().getName();
|
||||
toFireEvents.addAll(getPointersUnder(url));
|
||||
toFireEvents.addAll(getPointersUnder(url, false));
|
||||
}
|
||||
else if (event instanceof VFileMoveEvent) {
|
||||
final VFileMoveEvent moveEvent = (VFileMoveEvent)event;
|
||||
List<VirtualFilePointer> pointers = getPointersUnder(moveEvent.getFile().getPath());
|
||||
List<VirtualFilePointer> pointers = getPointersUnder(moveEvent.getFile().getPath(), false);
|
||||
for (VirtualFilePointer pointer : pointers) {
|
||||
VirtualFile file = pointer.getFile();
|
||||
if (file != null) {
|
||||
@@ -465,7 +467,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
|
||||
else if (event instanceof VFilePropertyChangeEvent) {
|
||||
final VFilePropertyChangeEvent change = (VFilePropertyChangeEvent)event;
|
||||
if (VirtualFile.PROP_NAME.equals(change.getPropertyName())) {
|
||||
List<VirtualFilePointer> pointers = getPointersUnder(change.getFile().getPath());
|
||||
List<VirtualFilePointer> pointers = getPointersUnder(change.getFile().getPath(), false);
|
||||
for (VirtualFilePointer pointer : pointers) {
|
||||
VirtualFile file = pointer.getFile();
|
||||
if (file != null) {
|
||||
@@ -488,6 +490,11 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
|
||||
event.fireBefore();
|
||||
}
|
||||
|
||||
if (!toFireEvents.isEmpty()) {
|
||||
VirtualFilePointer[] arr = toFireEvents.toArray(new VirtualFilePointer[toFireEvents.size()]);
|
||||
myBus.syncPublisher(VirtualFilePointerListener.TOPIC).beforeValidityChanged(arr);
|
||||
}
|
||||
|
||||
myPointersToUdate = toFireEvents;
|
||||
myUrlsToUpdate = toUpdateUrl;
|
||||
}
|
||||
@@ -518,6 +525,11 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
|
||||
event.fireAfter();
|
||||
}
|
||||
|
||||
if (!myPointersToUdate.isEmpty()) {
|
||||
VirtualFilePointer[] arr = myPointersToUdate.toArray(new VirtualFilePointer[myPointersToUdate.size()]);
|
||||
myBus.syncPublisher(VirtualFilePointerListener.TOPIC).beforeValidityChanged(arr);
|
||||
}
|
||||
|
||||
myUrlsToUpdate = null;
|
||||
myEvents = null;
|
||||
myPointersToUdate = null;
|
||||
|
||||
@@ -247,7 +247,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
|
||||
connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
|
||||
public void beforeRootsChange(ModuleRootEvent event) {
|
||||
if (!event.isCausedByFileTypesChange()) {
|
||||
fail("Root modification in LightIdeaTestCase is not allowed.");
|
||||
//TODO: uncomment fail("Root modification in LightIdeaTestCase is not allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user