From dd2d5f651a744ebc42fbb23aad03518881f73e20 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 7 Nov 2013 19:31:02 +0100 Subject: [PATCH] platform: ensure event file validity on dropping symlink target --- .../vfs/newvfs/events/VFileCreateEvent.java | 10 ++- .../newvfs/persistent/PersistentFSImpl.java | 1 + .../vfs/local/LocalFileSystemTest.java | 75 ++++++++++++++++++- 3 files changed, 81 insertions(+), 5 deletions(-) diff --git a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCreateEvent.java b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCreateEvent.java index b75988bc3bd1..e3a9b9040e32 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCreateEvent.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCreateEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,6 +63,10 @@ public class VFileCreateEvent extends VFileEvent { return myParent; } + public boolean isReCreation() { + return myReCreation; + } + @NonNls @Override public String toString() { @@ -81,6 +85,10 @@ public class VFileCreateEvent extends VFileEvent { return myCreatedFile = myParent.findChild(myChildName); } + public void resetCache() { + myCreatedFile = null; + } + @NotNull @Override public VirtualFileSystem getFileSystem() { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index 62ab743ac908..30ca7fe152b6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -770,6 +770,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone VirtualFile changedParent = null; if (event instanceof VFileCreateEvent) { changedParent = ((VFileCreateEvent)event).getParent(); + ((VFileCreateEvent)event).resetCache(); } else if (event instanceof VFileDeleteEvent) { changedParent = ((VFileDeleteEvent)event).getFile().getParent(); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java index c63f68599cde..e53f4007022e 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java @@ -16,17 +16,17 @@ package com.intellij.openapi.vfs.local; import com.intellij.ide.GeneralSettings; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileAttributes; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.IoTestUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.*; -import com.intellij.openapi.vfs.newvfs.ManagingFS; -import com.intellij.openapi.vfs.newvfs.NewVirtualFile; -import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; -import com.intellij.openapi.vfs.newvfs.RefreshQueue; +import com.intellij.openapi.vfs.newvfs.*; +import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent; import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent; +import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile; import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry; @@ -34,13 +34,40 @@ import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl; import com.intellij.testFramework.PlatformLangTestCase; import com.intellij.testFramework.PlatformTestUtil; +import com.intellij.util.messages.MessageBusConnection; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.List; import java.util.Locale; public class LocalFileSystemTest extends PlatformLangTestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + + MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(myTestRootDisposable); + connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { + @Override public void before(@NotNull List events) { checkFiles(events, true); } + + @Override public void after(@NotNull List events) { checkFiles(events, false); } + + private void checkFiles(List events, boolean before) { + for (VFileEvent event : events) { + VirtualFile file = event.getFile(); + if (file != null) { + boolean shouldBeInvalid = + event instanceof VFileCreateEvent && before && !((VFileCreateEvent)event).isReCreation() || + event instanceof VFileDeleteEvent && !before; + assertEquals(event.toString(), !shouldBeInvalid, file.isValid()); + } + } + } + }); + } + public void testChildrenAccessedButNotCached() throws Exception { File dir = createTempDirectory(false); ManagingFS managingFS = ManagingFS.getInstance(); @@ -474,4 +501,44 @@ public class LocalFileSystemTest extends PlatformLangTestCase { assertFalse(subFile.isDirty()); assertFalse(subDir.isDirty()); } + + public void testSymlinkTargetBlink() throws Exception { + if (!SystemInfo.areSymLinksSupported) { + System.err.println("Ignored: symlinks not supported"); + return; + } + + File top = createTempDirectory(true); + File target = IoTestUtil.createTestDir(top, "target"); + File link = IoTestUtil.createSymLink(target.getPath(), top.getPath() + "/link"); + + LocalFileSystem lfs = LocalFileSystem.getInstance(); + VirtualFile vTop = lfs.refreshAndFindFileByIoFile(top); + assertNotNull(vTop); + assertTrue(vTop.isValid()); + VirtualFile vTarget = lfs.refreshAndFindFileByIoFile(target); + assertNotNull(vTarget); + assertTrue(vTarget.isValid()); + VirtualFile vLink = lfs.refreshAndFindFileByIoFile(link); + assertNotNull(vLink); + assertTrue(vLink.isValid()); + assertTrue(vLink.isDirectory()); + + FileUtil.delete(target); + vTop.refresh(false, true); + assertFalse(vTarget.isValid()); + assertFalse(vLink.isValid()); + vLink = lfs.refreshAndFindFileByIoFile(link); + assertNotNull(vLink); + assertTrue(vLink.isValid()); + assertFalse(vLink.isDirectory()); + + FileUtil.createDirectory(target); + vTop.refresh(false, true); + assertFalse(vLink.isValid()); + vLink = lfs.refreshAndFindFileByIoFile(link); + assertNotNull(vLink); + assertTrue(vLink.isValid()); + assertTrue(vLink.isDirectory()); + } }