From 92dc5f4f193550d746fea6f4b2f732966b01dc4f Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 25 Nov 2010 14:37:01 +0300 Subject: [PATCH] IDEA-61180: When file is renamed, breakpoint file path is not updated --- .../vfs/VirtualFileUrlChangeAdapter.java | 40 +++++++++ .../impl/breakpoints/XLineBreakpointImpl.java | 8 ++ .../breakpoints/XLineBreakpointManager.java | 14 +++- .../UpdateBreakpointsAfterRenameTest.java | 81 +++++++++++++++++++ .../intellij/xdebugger/XDebuggerTestCase.java | 8 +- platform/xdebugger-impl/xdebugger-impl.iml | 3 + 6 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/openapi/vfs/VirtualFileUrlChangeAdapter.java create mode 100644 platform/xdebugger-impl/testSrc/com/intellij/xdebugger/UpdateBreakpointsAfterRenameTest.java diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/VirtualFileUrlChangeAdapter.java b/platform/platform-impl/src/com/intellij/openapi/vfs/VirtualFileUrlChangeAdapter.java new file mode 100644 index 000000000000..166f756be6b6 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/VirtualFileUrlChangeAdapter.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2010 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.vfs; + +/** + * @author nik + */ +public abstract class VirtualFileUrlChangeAdapter extends VirtualFileAdapter { + @Override + public void fileMoved(VirtualFileMoveEvent event) { + String oldUrl = event.getOldParent().getUrl() + "/" + event.getFileName(); + String newUrl = event.getNewParent().getUrl() + "/" + event.getFileName(); + fileUrlChanged(oldUrl, newUrl); + } + + protected abstract void fileUrlChanged(String oldUrl, String newUrl); + + public void propertyChanged(VirtualFilePropertyEvent event) { + if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) { + final VirtualFile parent = event.getFile().getParent(); + if (parent != null) { + final String parentUrl = parent.getUrl(); + fileUrlChanged(parentUrl + "/" + event.getOldValue(), parentUrl + "/" + event.getNewValue()); + } + } + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java index 446fe28ab580..b7f931f603d6 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java @@ -295,6 +295,14 @@ public class XLineBreakpointImpl

extends XBreak } } + public void setFileUrl(final String newUrl) { + if (!Comparing.equal(getFileUrl(), newUrl)) { + myState.setFileUrl(newUrl); + mySourcePosition = null; + fireBreakpointChanged(); + } + } + private void setLine(final int line) { if (getLine() != line) { myState.setLine(line); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java index 3650bd17e854..b873078fcd10 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java @@ -36,7 +36,8 @@ import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.*; import com.intellij.psi.PsiDocumentManager; import com.intellij.util.containers.BidirectionalMap; import com.intellij.util.ui.update.MergingUpdateQueue; @@ -82,6 +83,17 @@ public class XLineBreakpointManager { myDependentBreakpointManager.removeListener(myDependentBreakpointListener); } }); + VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileUrlChangeAdapter() { + @Override + protected void fileUrlChanged(String oldUrl, String newUrl) { + for (XLineBreakpointImpl breakpoint : myBreakpoints.keySet()) { + final String url = breakpoint.getFileUrl(); + if (FileUtil.startsWith(url, oldUrl)) { + breakpoint.setFileUrl(newUrl + url.substring(oldUrl.length())); + } + } + } + }, project); } myBreakpointsUpdateQueue = new MergingUpdateQueue("XLine breakpoints", 300, true, null, project); diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/UpdateBreakpointsAfterRenameTest.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/UpdateBreakpointsAfterRenameTest.java new file mode 100644 index 000000000000..e3a2405bd6dd --- /dev/null +++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/UpdateBreakpointsAfterRenameTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2010 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.testFramework.PlatformTestCase; +import com.intellij.xdebugger.breakpoints.XBreakpointManager; +import com.intellij.xdebugger.breakpoints.XLineBreakpoint; + +import java.io.File; + +/** + * @author nik + */ +public class UpdateBreakpointsAfterRenameTest extends PlatformTestCase { + private File myTempDirectory; + + public UpdateBreakpointsAfterRenameTest() { + initPlatformLangPrefix(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + myTempDirectory = createTempDirectory(); + } + + public void testRenameFile() throws Exception { + final VirtualFile file = createFile("file.txt"); + XLineBreakpoint b = putBreakpoint(file); + file.rename(this, "file2.txt"); + assertTrue(b.getFileUrl().endsWith("file2.txt")); + assertSame(b, getBreakpointManager().findBreakpointAtLine(XDebuggerTestCase.MY_LINE_BREAKPOINT_TYPE, file, 0)); + } + + public void testMoveFile() throws Exception { + final VirtualFile file = createFile("dir/a.txt"); + final VirtualFile targetDir = createFile("dir2/b.txt").getParent(); + final XLineBreakpoint b = putBreakpoint(file); + file.move(this, targetDir); + assertTrue(b.getFileUrl().endsWith("dir2/a.txt")); + } + + public void testRenameParentDir() throws Exception { + final VirtualFile file = createFile("dir/x.txt"); + final XLineBreakpoint b = putBreakpoint(file); + file.getParent().rename(this, "dir2"); + assertTrue(b.getFileUrl().endsWith("dir2/x.txt")); + } + + private XLineBreakpoint putBreakpoint(final VirtualFile file) { + return getBreakpointManager().addLineBreakpoint(XDebuggerTestCase.MY_LINE_BREAKPOINT_TYPE, file.getUrl(), 0, null); + } + + private VirtualFile createFile(String path) { + final File ioFile = new File(myTempDirectory, FileUtil.toSystemDependentName(path)); + FileUtil.createIfDoesntExist(ioFile); + final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile); + assertNotNull(virtualFile); + return virtualFile; + } + + public XBreakpointManager getBreakpointManager() { + return XDebuggerManager.getInstance(myProject).getBreakpointManager(); + } +} diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestCase.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestCase.java index 8f67ac31a34b..f81b60cba596 100644 --- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestCase.java +++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestCase.java @@ -33,7 +33,7 @@ import org.picocontainer.MutablePicoContainer; * @author nik */ public abstract class XDebuggerTestCase extends PlatformLiteFixture { - protected static final MyLineBreakpointType MY_LINE_BREAKPOINT_TYPE = new MyLineBreakpointType(); + public static final MyLineBreakpointType MY_LINE_BREAKPOINT_TYPE = new MyLineBreakpointType(); protected static final MySimpleBreakpointType MY_SIMPLE_BREAKPOINT_TYPE = new MySimpleBreakpointType(); @Override @@ -46,10 +46,14 @@ public abstract class XDebuggerTestCase extends PlatformLiteFixture { MutablePicoContainer container = getApplication().getPicoContainer(); registerComponentImplementation(container, EditorFactory.class, MockEditorFactory.class); - registerComponentImplementation(container, VirtualFileManager.class, MockVirtualFileManager.class); + registerVfsComponents(container); registerComponentImplementation(container, HttpFileSystem.class, HttpFileSystemImpl.class); } + protected void registerVfsComponents(MutablePicoContainer container) { + registerComponentImplementation(container, VirtualFileManager.class, MockVirtualFileManager.class); + } + public static class MyLineBreakpointType extends XLineBreakpointType { public MyLineBreakpointType() { super("testLine", "239"); diff --git a/platform/xdebugger-impl/xdebugger-impl.iml b/platform/xdebugger-impl/xdebugger-impl.iml index 0dddb25ce6c6..fe6cfde3d218 100644 --- a/platform/xdebugger-impl/xdebugger-impl.iml +++ b/platform/xdebugger-impl/xdebugger-impl.iml @@ -12,6 +12,9 @@ + + +