OC-6693 (more accurate fix)

This commit is contained in:
Roman Shevchenko
2013-03-06 09:34:04 +01:00
parent 21c6bce697
commit 48ff83253e
3 changed files with 67 additions and 30 deletions
@@ -348,14 +348,14 @@ public class FileWatcher {
public boolean isWatched(@NotNull final VirtualFile file) {
if (isOperational()) {
synchronized (myLock) {
return !checkWatchable(file.getPresentableUrl(), true, false).isEmpty();
return !checkWatchable(file.getPresentableUrl(), true, true).isEmpty();
}
}
return false;
}
@NotNull
private Collection<String> checkWatchable(String reportedPath, boolean isExact, boolean checkRootParents) {
private Collection<String> checkWatchable(String reportedPath, boolean isExact, boolean fastPath) {
if (reportedPath == null) return Collections.emptyList();
myAllPaths.clear();
@@ -372,26 +372,33 @@ public class FileWatcher {
myWatchedPaths.clear();
ext:
for (String path : myAllPaths) {
if (fastPath && !myWatchedPaths.isEmpty()) break;
for (String root : myFlatWatchRoots) {
if (FileUtil.pathsEqual(path, root)) {
myWatchedPaths.add(path);
continue ext;
}
if (isExact) {
String parentPath = new File(path).getParent();
if (parentPath != null && FileUtil.pathsEqual(parentPath, root)) {
myWatchedPaths.add(path);
continue ext;
}
}
}
for (String root : myRecursiveWatchRoots) {
if (FileUtil.startsWith(path, root)) {
myWatchedPaths.add(path);
continue ext;
}
if (checkRootParents && FileUtil.startsWith(root, path)) {
myWatchedPaths.add(root);
continue ext;
}
}
String checkPath = isExact ? new File(path).getParent() : path;
for (String root : myFlatWatchRoots) {
if (FileUtil.pathsEqual(checkPath, root)) {
myWatchedPaths.add(path);
continue ext;
}
if (checkRootParents && FileUtil.startsWith(root, checkPath)) {
myWatchedPaths.add(root);
continue ext;
if (!isExact) {
String parentPath = new File(root).getParent();
if (parentPath != null && FileUtil.pathsEqual(path, parentPath)) {
myWatchedPaths.add(root);
continue ext;
}
}
}
}
@@ -538,7 +545,7 @@ public class FileWatcher {
synchronized (myLock) {
boolean exactPath = op != WatcherOp.DIRTY && op != WatcherOp.RECDIRTY;
Collection<String> paths = checkWatchable(path, exactPath, true);
Collection<String> paths = checkWatchable(path, exactPath, false);
if (paths.isEmpty()) {
if (LOG.isDebugEnabled()) {
@@ -17,6 +17,7 @@ package com.intellij.openapi.vfs.impl.local;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.io.FileUtil;
@@ -59,7 +60,18 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
public WatchRequestImpl(String rootPath, boolean toWatchRecursively) throws FileNotFoundException {
int index = rootPath.indexOf(JarFileSystem.JAR_SEPARATOR);
if (index >= 0) rootPath = rootPath.substring(0, index);
File rootFile = new File(FileUtil.toSystemDependentName(rootPath));
if (index > 0 || !rootFile.isDirectory()) {
File parentFile = rootFile.getParentFile();
if (parentFile == null) {
throw new FileNotFoundException(rootPath);
}
if (!parentFile.getPath().equals(PathManager.getSystemPath()) || !rootFile.mkdir()) {
rootFile = parentFile;
}
}
myFSRootPath = rootFile.getAbsolutePath();
myRootPath = FileUtil.toSystemIndependentName(myFSRootPath);
myToWatchRecursively = toWatchRecursively;
@@ -266,28 +278,27 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
private void storeRefreshStatusToFiles() {
if (myWatcher.isOperational()) {
// TODO: different ways to mark dirty for all these cases
final FileWatcher.DirtyPaths dirtyPaths = myWatcher.getDirtyPaths();
FileWatcher.DirtyPaths dirtyPaths = myWatcher.getDirtyPaths();
markPathsDirty(dirtyPaths.dirtyPaths);
markFlatDirsDirty(dirtyPaths.dirtyDirectories);
markRecursiveDirsDirty(dirtyPaths.dirtyPathsRecursive);
}
}
private void markPathsDirty(final List<String> dirtyFiles) {
for (String dirtyFile : dirtyFiles) {
VirtualFile file = findFileByPathIfCached(dirtyFile);
private void markPathsDirty(List<String> dirtyPaths) {
for (String dirtyPath : dirtyPaths) {
VirtualFile file = findFileByPathIfCached(dirtyPath);
if (file instanceof NewVirtualFile) {
((NewVirtualFile)file).markDirty();
}
}
}
private void markFlatDirsDirty(final List<String> dirtyFiles) {
for (String dirtyFile : dirtyFiles) {
VirtualFile file = findFileByPathIfCached(dirtyFile);
private void markFlatDirsDirty(List<String> dirtyPaths) {
for (String dirtyPath : dirtyPaths) {
VirtualFile file = findFileOrParentIfCached(dirtyPath);
if (file instanceof NewVirtualFile) {
final NewVirtualFile nvf = (NewVirtualFile)file;
NewVirtualFile nvf = (NewVirtualFile)file;
nvf.markDirty();
for (VirtualFile child : nvf.getCachedChildren()) {
((NewVirtualFile)child).markDirty();
@@ -296,15 +307,26 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
}
}
private void markRecursiveDirsDirty(final List<String> dirtyFiles) {
for (String dirtyFile : dirtyFiles) {
VirtualFile file = findFileByPathIfCached(dirtyFile);
private void markRecursiveDirsDirty(List<String> dirtyPaths) {
for (String dirtyPath : dirtyPaths) {
VirtualFile file = findFileOrParentIfCached(dirtyPath);
if (file instanceof NewVirtualFile) {
((NewVirtualFile)file).markDirtyRecursively();
}
}
}
private VirtualFile findFileOrParentIfCached(String path) {
VirtualFile file = findFileByPathIfCached(path);
if (file == null) {
String parentPath = new File(path).getParent();
if (parentPath != null) {
file = findFileByPathIfCached(parentPath);
}
}
return file;
}
public void markSuspiciousFilesDirty(List<VirtualFile> files) {
storeRefreshStatusToFiles();
@@ -521,6 +521,14 @@ public class FileWatcherTest extends PlatformLangTestCase {
assertTrue(rootDir2.renameTo(rootDir));
assertEvent(VFileEvent.class, rootDir.getPath(), rootDir2.getPath());
myAccept = true;
assertTrue(FileUtil.delete(rootDir));
assertEvent(VFileDeleteEvent.class, rootDir.getPath());
myAccept = true;
assertTrue(rootDir.mkdirs());
assertEvent(VFileCreateEvent.class, rootDir.getPath());
myAccept = true;
assertTrue(FileUtil.delete(topDir));
assertEvent(VFileDeleteEvent.class, topDir.getPath());