FileDocumentSynchronizationVetoListener converted to extension point and cleaned up

This commit is contained in:
Dmitry Jemerov
2011-09-09 12:22:20 +02:00
parent c82204d80f
commit 4aabca15b4
11 changed files with 81 additions and 115 deletions
@@ -50,9 +50,6 @@ public abstract class FileDocumentManager implements SavingRequestor {
public abstract boolean isDocumentUnsaved(@NotNull Document document);
public abstract boolean isFileModified(@NotNull VirtualFile file);
public abstract void addFileDocumentSynchronizationVetoer(@NotNull FileDocumentSynchronizationVetoListener vetoer);
public abstract void removeFileDocumentSynchronizationVetoer(@NotNull FileDocumentSynchronizationVetoListener vetoer);
public abstract void reloadFromDisk(@NotNull Document document);
@NotNull
@@ -43,12 +43,12 @@ public interface FileDocumentManagerListener extends EventListener {
void beforeAllDocumentsSaving();
/**
* NOTE: Vetoing facility is deprecated in this listener implement {@link com.intellij.openapi.fileEditor.FileDocumentSynchronizationVetoListener} instead.
* NOTE: Vetoing facility is deprecated in this listener implement {@link FileDocumentSynchronizationVetoer} instead.
*/
void beforeDocumentSaving(Document document);
/**
* NOTE: Vetoing facility is deprecated in this listener implement {@link com.intellij.openapi.fileEditor.FileDocumentSynchronizationVetoListener} instead.
* NOTE: Vetoing facility is deprecated in this listener implement {@link FileDocumentSynchronizationVetoer} instead.
*/
void beforeFileContentReload(VirtualFile file, Document document);
@@ -20,11 +20,12 @@
package com.intellij.openapi.fileEditor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.vfs.VirtualFile;
import java.util.EventListener;
public interface FileDocumentSynchronizationVetoer {
ExtensionPointName<FileDocumentSynchronizationVetoer> EP_NAME = ExtensionPointName.create("com.intellij.fileDocumentSynchronizationVetoer");
public interface FileDocumentSynchronizationVetoListener extends EventListener {
void beforeDocumentSaving(Document document) throws VetoDocumentSavingException;
void beforeFileContentReload(VirtualFile file, Document document) throws VetoDocumentReloadException;
boolean maySaveDocument(Document document);
boolean mayReloadFileContent(VirtualFile file, Document document);
}
@@ -1,19 +0,0 @@
/*
* Copyright 2000-2009 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;
public class VetoDocumentReloadException extends Exception {
}
@@ -1,19 +0,0 @@
/*
* Copyright 2000-2009 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;
public class VetoDocumentSavingException extends Exception {
}
@@ -34,6 +34,7 @@ import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.fileTypes.BinaryFileTypeDecompilers;
import com.intellij.openapi.fileTypes.FileType;
@@ -52,10 +53,8 @@ import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
import com.intellij.psi.ExternalChangeAction;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.UIBundle;
import com.intellij.util.EventDispatcher;
import com.intellij.util.containers.ConcurrentHashSet;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -79,8 +78,6 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
private final Set<Document> myUnsavedDocuments = new ConcurrentHashSet<Document>();
private final EventDispatcher<FileDocumentSynchronizationVetoListener> myVetoDispatcher = EventDispatcher.create(FileDocumentSynchronizationVetoListener.class);
private final VirtualFileManager myVirtualFileManager;
private final MessageBus myBus;
@@ -291,14 +288,11 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
if (!file.isValid()) return;
}
try {
for (FileDocumentSynchronizationVetoListener listener : myVetoDispatcher.getListeners()) {
listener.beforeDocumentSaving(document);
for (FileDocumentSynchronizationVetoer vetoer : Extensions.getExtensions(FileDocumentSynchronizationVetoer.EP_NAME)) {
if (!vetoer.maySaveDocument(document)) {
return;
}
}
catch (VetoDocumentSavingException e) {
return;
}
try {
myBus.syncPublisher(AppTopics.FILE_DOCUMENT_SYNC).beforeDocumentSaving(document);
@@ -416,17 +410,6 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
return doc != null && isDocumentUnsaved(doc) && doc.getModificationStamp() != file.getModificationStamp();
}
public void addFileDocumentSynchronizationVetoer(@NotNull FileDocumentSynchronizationVetoListener vetoer) {
myVetoDispatcher.addListener(vetoer);
}
public void removeFileDocumentSynchronizationVetoer(@NotNull FileDocumentSynchronizationVetoListener vetoer) {
myVetoDispatcher.removeListener(vetoer);
}
private final Map<FileDocumentManagerListener, MessageBusConnection> myAdapters
= new HashMap<FileDocumentManagerListener, MessageBusConnection>();
public void propertyChanged(final VirtualFilePropertyEvent event) {
if (VirtualFile.PROP_WRITABLE.equals(event.getPropertyName())) {
final VirtualFile file = event.getFile();
@@ -500,15 +483,9 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
public void reloadFromDisk(@NotNull final Document document) {
ApplicationManager.getApplication().assertIsDispatchThread();
final VirtualFile file = getFile(document);
try {
fireBeforeFileContentReload(file, document);
}
catch (VetoDocumentReloadException e) {
if (!fireBeforeFileContentReload(file, document)) {
return;
}
catch (Exception e) {
LOG.error(e);
}
final Project project = ProjectLocator.getInstance().guessProjectForFile(file);
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@@ -632,14 +609,15 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
}
}
private void fireBeforeFileContentReload(final VirtualFile file, final Document document) throws VetoDocumentReloadException {
List<FileDocumentSynchronizationVetoListener> listeners = myVetoDispatcher.getListeners();
for (FileDocumentSynchronizationVetoListener listener : listeners) {
private boolean fireBeforeFileContentReload(final VirtualFile file, final Document document) {
for (FileDocumentSynchronizationVetoer vetoer : Extensions.getExtensions(FileDocumentSynchronizationVetoer.EP_NAME)) {
try {
listener.beforeFileContentReload(file, document);
if (!vetoer.mayReloadFileContent(file, document)) {
return false;
}
}
catch (AbstractMethodError e) {
// Do nothing. Some listener just does not implement this method yet.
catch (Exception e) {
LOG.error(e);
}
}
@@ -647,6 +625,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
for (FileDocumentManagerListener listener : getListeners()) {
listener.beforeFileContentReload(file, document);
}
return true;
}
private void fireFileContentLoaded(final VirtualFile file, final DocumentEx document) {
@@ -124,4 +124,5 @@
<extensionPoint name="editorHighlighterProvider" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint"/>
<extensionPoint name="fileDocumentManagerListener" interface="com.intellij.openapi.fileEditor.FileDocumentManagerListener"/>
<extensionPoint name="exceptionFilter" interface="com.intellij.execution.filters.ExceptionFilterFactory"/>
<extensionPoint name="fileDocumentSynchronizationVetoer" interface="com.intellij.openapi.fileEditor.FileDocumentSynchronizationVetoer"/>
</extensionPoints>
@@ -29,4 +29,5 @@
<keymapExtension implementation="com.intellij.openapi.vcs.impl.VcsKeymapExtension"/>
<fileTypeFactory implementation="com.intellij.openapi.vcs.impl.VcsFileTypeFactory"/>
<virtualFileSystem key="vcs" implementationClass="com.intellij.openapi.vcs.vfs.VcsFileSystem"/>
<fileDocumentSynchronizationVetoer implementation="com.intellij.openapi.vcs.changes.SaveCommittingDocumentsVetoer"/>
</extensions>
@@ -3,7 +3,6 @@ package com.intellij.mock;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileDocumentSynchronizationVetoListener;
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.project.Project;
@@ -75,14 +74,6 @@ public class MockFileDocumentManagerImpl extends FileDocumentManager {
return false;
}
@Override
public void addFileDocumentSynchronizationVetoer(@NotNull FileDocumentSynchronizationVetoListener vetoer) {
}
@Override
public void removeFileDocumentSynchronizationVetoer(@NotNull FileDocumentSynchronizationVetoListener vetoer) {
}
@Override
public void reloadFromDisk(@NotNull Document document) {
}
@@ -0,0 +1,53 @@
/*
* Copyright 2000-2011 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.vcs.changes;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentSynchronizationVetoer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.changes.ui.CommitHelper;
import com.intellij.openapi.vfs.VirtualFile;
import java.util.Collections;
/**
* @author yole
*/
public class SaveCommittingDocumentsVetoer implements FileDocumentSynchronizationVetoer {
private final VetoSavingCommittingDocumentsAdapter myAdapter;
public SaveCommittingDocumentsVetoer(VetoSavingCommittingDocumentsAdapter adapter) {
myAdapter = adapter;
}
public boolean maySaveDocument(Document document) {
final Object beingCommitted = document.getUserData(CommitHelper.DOCUMENT_BEING_COMMITTED_KEY);
if (beingCommitted == VetoSavingCommittingDocumentsAdapter.SAVE_DENIED) {
return false;
}
if (beingCommitted instanceof Project) {
boolean allowSave = myAdapter.showAllowSaveDialog((Project) beingCommitted, Collections.singletonList(document));
if (!allowSave) {
return false;
}
}
return true;
}
public boolean mayReloadFileContent(VirtualFile file, Document document) {
return true;
}
}
@@ -26,7 +26,8 @@ import com.intellij.AppTopics;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
@@ -36,11 +37,10 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class VetoSavingCommittingDocumentsAdapter implements ApplicationComponent, FileDocumentSynchronizationVetoListener {
private static final Object SAVE_DENIED = new Object();
public class VetoSavingCommittingDocumentsAdapter implements ApplicationComponent {
static final Object SAVE_DENIED = new Object();
private final FileDocumentManager myFileDocumentManager;
@@ -48,30 +48,12 @@ public class VetoSavingCommittingDocumentsAdapter implements ApplicationComponen
myFileDocumentManager = fileDocumentManager;
}
public void beforeDocumentSaving(Document document) throws VetoDocumentSavingException {
final Object beingCommitted = document.getUserData(CommitHelper.DOCUMENT_BEING_COMMITTED_KEY);
if (beingCommitted == SAVE_DENIED) {
throw new VetoDocumentSavingException();
}
if (beingCommitted instanceof Project) {
boolean allowSave = showAllowSaveDialog((Project) beingCommitted, Collections.singletonList(document));
if (!allowSave) {
throw new VetoDocumentSavingException();
}
}
}
public void beforeFileContentReload(VirtualFile file, Document document) throws VetoDocumentReloadException {
}
@NonNls @NotNull
public String getComponentName() {
return "VetoSavingComittingDocumentsAdapter";
}
public void initComponent() {
myFileDocumentManager.addFileDocumentSynchronizationVetoer(this);
ApplicationManager.getApplication().getMessageBus().connect().subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerAdapter() {
@Override
public void beforeAllDocumentsSaving() {
@@ -96,10 +78,9 @@ public class VetoSavingCommittingDocumentsAdapter implements ApplicationComponen
}
public void disposeComponent() {
myFileDocumentManager.removeFileDocumentSynchronizationVetoer(this);
}
private boolean showAllowSaveDialog(Project project, List<Document> documentsToWarn) {
boolean showAllowSaveDialog(Project project, List<Document> documentsToWarn) {
StringBuilder messageBuilder = new StringBuilder("The following " + (documentsToWarn.size() == 1 ? "file is" : "files are") +
" currently being committed to the VCS. " +
"Saving now could cause inconsistent data to be committed.\n");
@@ -109,7 +90,7 @@ public class VetoSavingCommittingDocumentsAdapter implements ApplicationComponen
}
messageBuilder.append("Save the ").append(documentsToWarn.size() == 1 ? "file" : "files").append(" now?");
int rc = Messages.showOkCancelDialog(project, messageBuilder.toString(), "Save Files During Commit", "Save Now", "Postpone Save",
int rc = Messages.showOkCancelDialog(project, messageBuilder.toString(), "Save Files During Commit", "Save Now", "Postpone Save",
Messages.getQuestionIcon());
return rc == 0;
}