IDEA-107827 (do not lose a document after renaming a file to an unknown type)

This commit is contained in:
Roman Shevchenko
2013-05-29 21:18:10 +04:00
parent eff321ee12
commit 7053313c86
4 changed files with 102 additions and 22 deletions
@@ -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.
@@ -41,6 +41,8 @@ import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl;
import com.intellij.openapi.fileTypes.BinaryFileTypeDecompilers;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.UnknownFileType;
import com.intellij.openapi.project.*;
import com.intellij.openapi.project.ex.ProjectEx;
import com.intellij.openapi.ui.DialogBuilder;
@@ -79,6 +81,8 @@ import java.lang.reflect.Proxy;
import java.util.*;
import java.util.List;
import static com.intellij.reference.SoftReference.dereference;
public class FileDocumentManagerImpl extends FileDocumentManager implements ApplicationComponent, VirtualFileListener,
ProjectManagerListener, SafeWriteRequestor {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl");
@@ -226,16 +230,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
@Override
@Nullable
public Document getCachedDocument(@NotNull VirtualFile file) {
Reference<Document> reference = file.getUserData(DOCUMENT_KEY);
Document document = reference == null ? null : reference.get();
if (document != null && isBinaryWithoutDecompiler(file)) {
file.putUserData(DOCUMENT_KEY, null);
document.putUserData(FILE_KEY, null);
return null;
}
return document;
return dereference(file.getUserData(DOCUMENT_KEY));
}
public static void registerDocument(@NotNull final Document document, @NotNull VirtualFile virtualFile) {
@@ -536,21 +531,32 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
}
@Override
public void propertyChanged(final VirtualFilePropertyEvent event) {
public void propertyChanged(VirtualFilePropertyEvent event) {
final VirtualFile file = event.getFile();
if (VirtualFile.PROP_WRITABLE.equals(event.getPropertyName())) {
final VirtualFile file = event.getFile();
final Document document = getCachedDocument(file);
if (document == null) return;
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
if (document != null) {
ApplicationManager.getApplication().runWriteAction(new ExternalChangeAction() {
@Override
public void run() {
document.setReadOnly(!event.getFile().isWritable());
document.setReadOnly(!file.isWritable());
}
});
}
}
else if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) {
Document document = getCachedDocument(file);
if (document != null) {
FileType type = file.getFileType();
if (type == UnknownFileType.INSTANCE) {
// a file is linked to a document - chances are it is an "unknown text file" now
FileTypeManager.getInstance().detectFileTypeFromContent(file);
}
);
//myUnsavedDocuments.remove(document); //?
if (isBinaryWithoutDecompiler(file)) {
file.putUserData(DOCUMENT_KEY, null);
document.putUserData(FILE_KEY, null);
}
}
}
}
@@ -0,0 +1,67 @@
/*
* 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.
* 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.fileEditor;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.io.IoTestUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.LightPlatformLangTestCase;
import java.io.File;
import java.io.IOException;
public class RealFileDocumentManagerTest extends LightPlatformLangTestCase {
public void testFileTypeModificationDocumentPreservation() throws Exception {
File ioFile = IoTestUtil.createTestFile("test.html", "<html>some text</html>");
VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile);
assertNotNull(ioFile.getPath(), file);
FileDocumentManager documentManager = FileDocumentManager.getInstance();
Document original = documentManager.getDocument(file);
assertNotNull(file.getPath(), original);
renameFile(file, "test.wtf");
Document afterRename = documentManager.getDocument(file);
assertTrue(afterRename + " != " + original, afterRename == original);
}
public void testFileTypeChangeDocumentDetach() throws Exception {
File ioFile = IoTestUtil.createTestFile("test.html", "<html>some text</html>");
VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile);
assertNotNull(ioFile.getPath(), file);
FileDocumentManager documentManager = FileDocumentManager.getInstance();
Document original = documentManager.getDocument(file);
assertNotNull(file.getPath(), original);
renameFile(file, "test.png");
Document afterRename = documentManager.getDocument(file);
assertNull(afterRename + " != null", afterRename);
}
private static void renameFile(VirtualFile file, String newName) throws IOException {
AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(RealFileDocumentManagerTest.class);
try {
file.rename(RealFileDocumentManagerTest.class, newName);
}
finally {
token.finish();
}
}
}
@@ -17,6 +17,7 @@ package com.intellij.reference;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
/**
@@ -46,7 +47,7 @@ public class SoftReference<T> extends java.lang.ref.SoftReference<T> {
//}
@Nullable
public static <T> T dereference(@Nullable java.lang.ref.SoftReference<T> ref) {
public static <T> T dereference(@Nullable Reference<T> ref) {
return ref != null ? ref.get() : null;
}
}
@@ -237,7 +237,12 @@ public class IoTestUtil {
@NotNull
public static File createTestFile(@NotNull String name) throws IOException {
return createTestFile(new File(FileUtil.getTempDirectory()), name, null);
return createTestFile(name, null);
}
@NotNull
public static File createTestFile(@NotNull String name, @Nullable String content) throws IOException {
return createTestFile(new File(FileUtil.getTempDirectory()), name, content);
}
@NotNull
@@ -247,6 +252,7 @@ public class IoTestUtil {
@NotNull
public static File createTestFile(@NotNull File parent, @NotNull String name, @Nullable String content) throws IOException {
assertTrue(parent.getPath(), parent.isDirectory() || parent.mkdirs());
File file = new File(parent, name);
assertTrue(file.getPath(), file.createNewFile());
if (content != null) {