From 092aa296d0f208ceefe8d2b7046a397f11509c0b Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 13 Aug 2012 19:45:31 +0400 Subject: [PATCH] Refresh symlinks radically --- .../vfs/newvfs/persistent/RefreshWorker.java | 20 +++++++- .../vfs/local/SymlinkHandlingTest.java | 47 ++++++++++++++----- 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index 1d2454c4238f..6dcefd675e15 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -77,7 +77,9 @@ public class RefreshWorker { boolean checkFurther = true; final VirtualFileSystemEntry parent = file.getParent(); - if (parent != null && checkAndScheduleAttributesChange(parent, file, attributes)) { + if (parent != null && + (checkAndScheduleAttributesChange(parent, file, attributes) || + checkAndScheduleSymLinkTargetChange(parent, file, attributes, fs))) { // ignore everything else checkFurther = false; } @@ -201,6 +203,22 @@ public class RefreshWorker { } } + private boolean checkAndScheduleSymLinkTargetChange(@NotNull VirtualFileSystemEntry parent, + @NotNull VirtualFile child, + @NotNull FileAttributes childAttributes, + @NotNull NewVirtualFileSystem fs) { + if (childAttributes.isSymLink()) { + final String currentTarget = child.getCanonicalPath(); + final String upToDateTarget = fs.resolveSymLink(child); + if (!Comparing.equal(currentTarget, upToDateTarget)) { + scheduleDeletion(child); + scheduleReCreation(parent, child.getName(), childAttributes.isDirectory()); + return true; + } + } + return false; + } + private void scheduleWritableAttributeChange(@NotNull VirtualFileSystemEntry file, boolean currentWritable, boolean upToDateWritable) { myEvents.add(new VFilePropertyChangeEvent(null, file, VirtualFile.PROP_WRITABLE, currentWritable, upToDateWritable, true)); } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkHandlingTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkHandlingTest.java index 956f44fe865d..faf94e941fc8 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkHandlingTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkHandlingTest.java @@ -242,26 +242,51 @@ public class SymlinkHandlingTest extends LightPlatformLangTestCase { !vFile2.isValid() && vFile1 != null && !vFile1.isDirectory() && vFile1.isSymLink()); } - public void testLinkSwitch() throws Exception { - final File targetDir1 = createTempDirectory(myTempDir, "targetDir1", ""); - final File targetDir2 = createTempDirectory(myTempDir, "targetDir2", ""); + public void testDirLinkSwitch() throws Exception { + final File targetDir1 = createTempDirectory(myTempDir, "target1.", ".dir"); + final File targetDir2 = createTempDirectory(myTempDir, "target2.", ".dir"); assertTrue(new File(targetDir1, "child1.txt").createNewFile()); assertTrue(new File(targetDir2, "child11.txt").createNewFile()); assertTrue(new File(targetDir2, "child12.txt").createNewFile()); final File link = createTempLink(targetDir1.getPath(), myTempDir + "/link"); - VirtualFile vLink = refreshAndFind(link); - assertTrue("link=" + link + ", vLink=" + vLink, - vLink != null && vLink.isDirectory() && vLink.isSymLink()); - assertEquals(1, vLink.getChildren().length); + final VirtualFile vLink1 = refreshAndFind(link); + assertTrue("link=" + link + ", vLink=" + vLink1, + vLink1 != null && vLink1.isDirectory() && vLink1.isSymLink()); + assertEquals(1, vLink1.getChildren().length); assertTrue(link.toString(), link.delete()); createTempLink(targetDir2.getPath(), myTempDir + "/" + link.getName()); - vLink = refreshAndFind(link); - assertTrue("link=" + link + ", vLink=" + vLink, - vLink != null && vLink.isDirectory() && vLink.isSymLink()); - assertEquals(2, vLink.getChildren().length); + refresh(); + assertFalse(vLink1.isValid()); + final VirtualFile vLink2 = myFileSystem.findFileByIoFile(link); + assertTrue("link=" + link + ", vLink=" + vLink2, + vLink2 != null && vLink2.isDirectory() && vLink2.isSymLink()); + assertEquals(2, vLink2.getChildren().length); + } + + public void testFileLinkSwitch() throws Exception { + final File target1 = createTempFile(myTempDir, "target1.", ".txt"); + FileUtil.writeToFile(target1, "some text"); + final File target2 = createTempFile(myTempDir, "target2.", ".txt"); + FileUtil.writeToFile(target2, "some quite another text"); + + final File link = createTempLink(target1.getPath(), myTempDir + "/link"); + final VirtualFile vLink1 = refreshAndFind(link); + assertTrue("link=" + link + ", vLink=" + vLink1, + vLink1 != null && !vLink1.isDirectory() && vLink1.isSymLink()); + assertEquals(FileUtil.loadFile(target1), VfsUtilCore.loadText(vLink1)); + + assertTrue(link.toString(), link.delete()); + createTempLink(target2.getPath(), myTempDir + "/" + link.getName()); + + refresh(); + assertFalse(vLink1.isValid()); + final VirtualFile vLink2 = myFileSystem.findFileByIoFile(link); + assertTrue("link=" + link + ", vLink=" + vLink2, + vLink2 != null && !vLink2.isDirectory() && vLink2.isSymLink()); + assertEquals(FileUtil.loadFile(target2), VfsUtilCore.loadText(vLink2)); } public void testContentSynchronization() throws Exception {