mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-94515 (correct Unix paths splitting)
This commit is contained in:
+40
-27
@@ -20,8 +20,8 @@ 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.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -32,6 +32,7 @@ import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
|
||||
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.TimeoutUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -44,6 +45,8 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public final class LocalFileSystemImpl extends LocalFileSystemBase implements ApplicationComponent {
|
||||
private static final String FS_ROOT = "/";
|
||||
|
||||
private final Object myLock = new Object();
|
||||
private final List<WatchRequestImpl> myRootsToWatch = new ArrayList<WatchRequestImpl>();
|
||||
private TreeNode myNormalizedTree = null;
|
||||
@@ -107,7 +110,7 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
|
||||
private static class TreeNode {
|
||||
private WatchRequestImpl watchRequest = null;
|
||||
private Map<String, TreeNode> nodes = new HashMap<String, TreeNode>();
|
||||
private Map<String, TreeNode> nodes = ContainerUtil.newTroveMap(FileUtil.PATH_HASHING_STRATEGY);
|
||||
}
|
||||
|
||||
public LocalFileSystemImpl(@NotNull ManagingFS managingFS) {
|
||||
@@ -164,13 +167,12 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
synchronized (myLock) {
|
||||
TreeNode rootNode = new TreeNode();
|
||||
for (WatchRequestImpl request : myRootsToWatch) {
|
||||
request.myDominated = false;
|
||||
String rootPath = request.getRootPath();
|
||||
|
||||
TreeNode currentNode = rootNode;
|
||||
MainLoop:
|
||||
for (String subPath : rootPath.split("/")) {
|
||||
if (!SystemInfo.isFileSystemCaseSensitive) {
|
||||
subPath = subPath.toLowerCase();
|
||||
}
|
||||
for (String subPath : splitPath(rootPath)) {
|
||||
TreeNode nextNode = currentNode.nodes.get(subPath);
|
||||
if (nextNode != null) {
|
||||
currentNode = nextNode;
|
||||
@@ -228,6 +230,23 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
return result.toArray(new WatchRequestImpl[result.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> splitPath(@NotNull String path) {
|
||||
if (path.isEmpty()) {
|
||||
return ContainerUtil.emptyList();
|
||||
}
|
||||
|
||||
if (FS_ROOT.equals(path)) {
|
||||
return Collections.singletonList(FS_ROOT);
|
||||
}
|
||||
|
||||
List<String> parts = StringUtil.split(path, FS_ROOT);
|
||||
if (StringUtil.startsWithChar(path, '/')) {
|
||||
parts.add(0, FS_ROOT);
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
private static void visitTree(TreeNode rootNode, Consumer<TreeNode> consumer) {
|
||||
for (TreeNode node : rootNode.nodes.values()) {
|
||||
consumer.consume(node);
|
||||
@@ -242,10 +261,7 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
|
||||
String rootPath = request.getRootPath();
|
||||
TreeNode currentNode = myNormalizedTree;
|
||||
for (String subPath : rootPath.split("/")) {
|
||||
if (!SystemInfo.isFileSystemCaseSensitive) {
|
||||
subPath = subPath.toLowerCase();
|
||||
}
|
||||
for (String subPath : splitPath(rootPath)) {
|
||||
TreeNode nextNode = currentNode.nodes.get(subPath);
|
||||
if (nextNode == null) {
|
||||
return false;
|
||||
@@ -332,27 +348,24 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
private void setUpFileWatcher() {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
if (application.isDisposeInProgress() || !myWatcher.isOperational()) return;
|
||||
application.assertReadAccessAllowed();
|
||||
|
||||
application.runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
synchronized (myLock) {
|
||||
final WatchRequestImpl[] watchRequests = normalizeRootsForRefresh();
|
||||
final List<String> myRecursiveRoots = new ArrayList<String>();
|
||||
final List<String> myFlatRoots = new ArrayList<String>();
|
||||
synchronized (myLock) {
|
||||
final WatchRequestImpl[] watchRequests = normalizeRootsForRefresh();
|
||||
final List<String> myRecursiveRoots = new ArrayList<String>();
|
||||
final List<String> myFlatRoots = new ArrayList<String>();
|
||||
|
||||
for (WatchRequestImpl watchRequest : watchRequests) {
|
||||
if (watchRequest.isToWatchRecursively()) {
|
||||
myRecursiveRoots.add(watchRequest.myFSRootPath);
|
||||
}
|
||||
else {
|
||||
myFlatRoots.add(watchRequest.myFSRootPath);
|
||||
}
|
||||
}
|
||||
|
||||
myWatcher.setWatchRoots(myRecursiveRoots, myFlatRoots);
|
||||
for (WatchRequestImpl watchRequest : watchRequests) {
|
||||
if (watchRequest.isToWatchRecursively()) {
|
||||
myRecursiveRoots.add(watchRequest.myFSRootPath);
|
||||
}
|
||||
else {
|
||||
myFlatRoots.add(watchRequest.myFSRootPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
myWatcher.setWatchRoots(myRecursiveRoots, myFlatRoots);
|
||||
}
|
||||
}
|
||||
|
||||
private class StoreRefreshStatusThread extends Thread {
|
||||
|
||||
+52
-8
@@ -94,6 +94,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
|
||||
assertTrue(myWatcher.isOperational());
|
||||
|
||||
myAlarm = new Alarm(Alarm.ThreadToUse.OWN_THREAD, getProject());
|
||||
myTimeout = NATIVE_PROCESS_DELAY;
|
||||
|
||||
myConnection = ApplicationManager.getApplication().getMessageBus().connect();
|
||||
myConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
|
||||
@@ -225,15 +226,11 @@ public class FileWatcherTest extends PlatformLangTestCase {
|
||||
FileUtil.writeToFile(watchedFile, "new content");
|
||||
assertEvent(VFileContentChangeEvent.class, watchedFile.getAbsolutePath());
|
||||
|
||||
myTimeout = 10 * INTER_RESPONSE_DELAY;
|
||||
myAccept = true;
|
||||
try {
|
||||
myTimeout = 10 * INTER_RESPONSE_DELAY;
|
||||
FileUtil.writeToFile(unwatchedFile, "new content");
|
||||
assertEvent(VFileEvent.class);
|
||||
}
|
||||
finally {
|
||||
myTimeout = NATIVE_PROCESS_DELAY;
|
||||
}
|
||||
FileUtil.writeToFile(unwatchedFile, "new content");
|
||||
assertEvent(VFileEvent.class);
|
||||
myTimeout = NATIVE_PROCESS_DELAY;
|
||||
}
|
||||
finally {
|
||||
unwatch(request);
|
||||
@@ -506,6 +503,53 @@ public class FileWatcherTest extends PlatformLangTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testSwitchingToFsRoot() throws Exception {
|
||||
File topDir = IoTestUtil.createTestDir("top");
|
||||
File rootDir = IoTestUtil.createTestDir(topDir, "root");
|
||||
File file1 = IoTestUtil.createTestFile(topDir, "1.txt");
|
||||
File file2 = IoTestUtil.createTestFile(rootDir, "2.txt");
|
||||
refresh(topDir);
|
||||
|
||||
File fsRoot = new File(SystemInfo.isUnix ? "/" : topDir.getPath().substring(0, topDir.getPath().indexOf(File.separatorChar)));
|
||||
assertTrue("can't guess root of " + topDir, fsRoot.exists());
|
||||
|
||||
LocalFileSystem.WatchRequest request = watch(rootDir);
|
||||
try {
|
||||
myAccept = true;
|
||||
FileUtil.writeToFile(file1, "abc");
|
||||
FileUtil.writeToFile(file2, "abc");
|
||||
assertEvent(VFileContentChangeEvent.class, file2.getPath());
|
||||
|
||||
LocalFileSystem.WatchRequest rootRequest = watch(fsRoot);
|
||||
try {
|
||||
myTimeout = 10 * INTER_RESPONSE_DELAY;
|
||||
myAccept = true;
|
||||
FileUtil.writeToFile(file1, "12345");
|
||||
FileUtil.writeToFile(file2, "12345");
|
||||
assertEvent(VFileContentChangeEvent.class, file1.getPath(), file2.getPath());
|
||||
myTimeout = NATIVE_PROCESS_DELAY;
|
||||
}
|
||||
finally {
|
||||
unwatch(rootRequest);
|
||||
}
|
||||
|
||||
myAccept = true;
|
||||
FileUtil.writeToFile(file1, "");
|
||||
FileUtil.writeToFile(file2, "");
|
||||
assertEvent(VFileContentChangeEvent.class, file2.getPath());
|
||||
}
|
||||
finally {
|
||||
unwatch(request);
|
||||
}
|
||||
|
||||
myTimeout = 10 * INTER_RESPONSE_DELAY;
|
||||
myAccept = true;
|
||||
FileUtil.writeToFile(file1, "xyz");
|
||||
FileUtil.writeToFile(file2, "xyz");
|
||||
assertEvent(VFileEvent.class);
|
||||
myTimeout = NATIVE_PROCESS_DELAY;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private LocalFileSystem.WatchRequest watch(final File watchFile) {
|
||||
|
||||
@@ -86,6 +86,11 @@ public class ContainerUtil extends ContainerUtilRt {
|
||||
return new THashMap<K, V>();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <K, V> THashMap<K, V> newTroveMap(@NotNull TObjectHashingStrategy<K> strategy) {
|
||||
return new THashMap<K, V>(strategy);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() {
|
||||
return new IdentityHashMap<K, V>();
|
||||
|
||||
Reference in New Issue
Block a user