diff --git a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java index 2d204dc21458..f250b9a65956 100644 --- a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java +++ b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java @@ -25,6 +25,8 @@ import com.intellij.mock.MockFileDocumentManagerImpl; import com.intellij.mock.MockReferenceProvidersRegistry; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.impl.CoreCommandProcessor; import com.intellij.openapi.components.ExtensionAreas; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.impl.DocumentImpl; @@ -76,23 +78,22 @@ import java.util.concurrent.TimeoutException; */ public class CoreApplicationEnvironment { private final CoreFileTypeRegistry myFileTypeRegistry; - private final CoreEncodingRegistry myEncodingRegistry; protected final MockApplication myApplication; private final CoreLocalFileSystem myLocalFileSystem; protected final VirtualFileSystem myJarFileSystem; - private final Disposable myParentDisposable; + @NotNull private final Disposable myParentDisposable; public CoreApplicationEnvironment(@NotNull Disposable parentDisposable) { myParentDisposable = parentDisposable; Extensions.cleanRootArea(myParentDisposable); myFileTypeRegistry = new CoreFileTypeRegistry(); - myEncodingRegistry = new CoreEncodingRegistry(); + CoreEncodingRegistry encodingRegistry = new CoreEncodingRegistry(); myApplication = createApplication(myParentDisposable); ApplicationManager.setApplication(myApplication, new StaticGetter(myFileTypeRegistry), - new StaticGetter(myEncodingRegistry), + new StaticGetter(encodingRegistry), myParentDisposable); myLocalFileSystem = createLocalFileSystem(); myJarFileSystem = createJarFileSystem(); @@ -112,12 +113,12 @@ public class CoreApplicationEnvironment { registerComponentInstance(appContainer, VirtualFileManager.class, virtualFileManager); registerApplicationService(VirtualFilePointerManager.class, createVirtualFilePointerManager()); - myApplication.registerService(DefaultASTFactory.class, new CoreASTFactory()); - myApplication.registerService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl()); - myApplication.registerService(ReferenceProvidersRegistry.class, new MockReferenceProvidersRegistry()); - myApplication.registerService(StubTreeLoader.class, new CoreStubTreeLoader()); - myApplication.registerService(PsiReferenceService.class, new PsiReferenceServiceImpl()); - myApplication.registerService(MetaDataRegistrar.class, new MetaRegistry()); + registerApplicationService(DefaultASTFactory.class, new CoreASTFactory()); + registerApplicationService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl()); + registerApplicationService(ReferenceProvidersRegistry.class, new MockReferenceProvidersRegistry()); + registerApplicationService(StubTreeLoader.class, new CoreStubTreeLoader()); + registerApplicationService(PsiReferenceService.class, new PsiReferenceServiceImpl()); + registerApplicationService(MetaDataRegistrar.class, new MetaRegistry()); registerApplicationExtensionPoint(ContentBasedFileSubstitutor.EP_NAME, ContentBasedFileSubstitutor.class); registerExtensionPoint(Extensions.getRootArea(), BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint.class); @@ -127,8 +128,9 @@ public class CoreApplicationEnvironment { ProgressIndicatorProvider.ourInstance = createProgressIndicatorProvider(); - myApplication.registerService(JobLauncher.class, createJobLauncher()); - myApplication.registerService(CodeFoldingSettings.class, new CodeFoldingSettings()); + registerApplicationService(JobLauncher.class, createJobLauncher()); + registerApplicationService(CodeFoldingSettings.class, new CodeFoldingSettings()); + registerApplicationService(CommandProcessor.class, new CoreCommandProcessor()); } public void registerApplicationService(@NotNull Class serviceInterface, @NotNull T serviceImplementation) { @@ -256,32 +258,33 @@ public class CoreApplicationEnvironment { return myApplication; } + @NotNull public Disposable getParentDisposable() { return myParentDisposable; } - public void registerApplicationComponent(final Class interfaceClass, final T implementation) { + public void registerApplicationComponent(@NotNull Class interfaceClass, @NotNull T implementation) { registerComponentInstance(myApplication.getPicoContainer(), interfaceClass, implementation); } - public void registerFileType(FileType fileType, String extension) { + public void registerFileType(@NotNull FileType fileType, @NotNull String extension) { myFileTypeRegistry.registerFileType(fileType, extension); } - public void registerParserDefinition(ParserDefinition definition) { + public void registerParserDefinition(@NotNull ParserDefinition definition) { addExplicitExtension(LanguageParserDefinitions.INSTANCE, definition.getFileNodeType().getLanguage(), definition); } - public static void registerComponentInstance(final MutablePicoContainer container, final Class key, final T implementation) { + public static void registerComponentInstance(@NotNull MutablePicoContainer container, @NotNull Class key, @NotNull T implementation) { container.unregisterComponent(key); container.registerComponentInstance(key, implementation); } - public void addExplicitExtension(final LanguageExtension instance, final Language language, final T object) { + public void addExplicitExtension(@NotNull LanguageExtension instance, @NotNull Language language, @NotNull T object) { doAddExplicitExtension(instance, language, object); } - public void registerParserDefinition(Language language, ParserDefinition parserDefinition) { + public void registerParserDefinition(@NotNull Language language, @NotNull ParserDefinition parserDefinition) { addExplicitExtension(LanguageParserDefinitions.INSTANCE, language, parserDefinition); } @@ -303,7 +306,7 @@ public class CoreApplicationEnvironment { doAddExplicitExtension(instance, aClass, object); } - public void addExtension(ExtensionPointName name, final T extension) { + public void addExtension(@NotNull ExtensionPointName name, @NotNull final T extension) { final ExtensionPoint extensionPoint = Extensions.getRootArea().getExtensionPoint(name); extensionPoint.registerExtension(extension); Disposer.register(myParentDisposable, new Disposable() { @@ -315,28 +318,31 @@ public class CoreApplicationEnvironment { } - public static void registerExtensionPoint(final ExtensionsArea area, final ExtensionPointName extensionPointName, - final Class aClass) { + public static void registerExtensionPoint(@NotNull ExtensionsArea area, + @NotNull ExtensionPointName extensionPointName, + @NotNull Class aClass) { final String name = extensionPointName.getName(); registerExtensionPoint(area, name, aClass); } - public static void registerExtensionPoint(ExtensionsArea area, String name, Class aClass) { + public static void registerExtensionPoint(@NotNull ExtensionsArea area, @NotNull String name, @NotNull Class aClass) { if (!area.hasExtensionPoint(name)) { ExtensionPoint.Kind kind = aClass.isInterface() || (aClass.getModifiers() & Modifier.ABSTRACT) != 0 ? ExtensionPoint.Kind.INTERFACE : ExtensionPoint.Kind.BEAN_CLASS; area.registerExtensionPoint(name, aClass.getName(), kind); } } - public static void registerApplicationExtensionPoint(final ExtensionPointName extensionPointName, final Class aClass) { + public static void registerApplicationExtensionPoint(@NotNull ExtensionPointName extensionPointName, @NotNull Class aClass) { final String name = extensionPointName.getName(); registerExtensionPoint(Extensions.getRootArea(), name, aClass); } + @NotNull public CoreLocalFileSystem getLocalFileSystem() { return myLocalFileSystem; } + @NotNull public VirtualFileSystem getJarFileSystem() { return myJarFileSystem; } diff --git a/platform/platform-impl/src/com/intellij/openapi/command/CommandProcessorEx.java b/platform/core-impl/src/com/intellij/openapi/command/CommandProcessorEx.java similarity index 96% rename from platform/platform-impl/src/com/intellij/openapi/command/CommandProcessorEx.java rename to platform/core-impl/src/com/intellij/openapi/command/CommandProcessorEx.java index deba1eec5408..df22fdb8da8a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/CommandProcessorEx.java +++ b/platform/core-impl/src/com/intellij/openapi/command/CommandProcessorEx.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandLog.java b/platform/core-impl/src/com/intellij/openapi/command/impl/CommandLog.java similarity index 95% rename from platform/platform-impl/src/com/intellij/openapi/command/impl/CommandLog.java rename to platform/core-impl/src/com/intellij/openapi/command/impl/CommandLog.java index 0f257672be0c..14353098da5b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandLog.java +++ b/platform/core-impl/src/com/intellij/openapi/command/impl/CommandLog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. diff --git a/platform/core-impl/src/com/intellij/openapi/command/impl/CoreCommandProcessor.java b/platform/core-impl/src/com/intellij/openapi/command/impl/CoreCommandProcessor.java new file mode 100644 index 000000000000..266663e3c51c --- /dev/null +++ b/platform/core-impl/src/com/intellij/openapi/command/impl/CoreCommandProcessor.java @@ -0,0 +1,361 @@ +/* + * Copyright 2000-2014 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.command.impl; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandEvent; +import com.intellij.openapi.command.CommandListener; +import com.intellij.openapi.command.CommandProcessorEx; +import com.intellij.openapi.command.UndoConfirmationPolicy; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.EmptyRunnable; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Stack; + +public class CoreCommandProcessor extends CommandProcessorEx { + private static class CommandDescriptor { + public final Runnable myCommand; + public final Project myProject; + public String myName; + public Object myGroupId; + public final Document myDocument; + public final UndoConfirmationPolicy myUndoConfirmationPolicy; + + public CommandDescriptor(Runnable command, + Project project, + String name, + Object groupId, + UndoConfirmationPolicy undoConfirmationPolicy, + Document document) { + myCommand = command; + myProject = project; + myName = name; + myGroupId = groupId; + myUndoConfirmationPolicy = undoConfirmationPolicy; + myDocument = document; + } + + @Override + public String toString() { + return "'" + myName + "', group: '" + myGroupId + "'"; + } + } + + protected CommandDescriptor myCurrentCommand = null; + private final Stack myInterruptedCommands = new Stack(); + +// private HashMap myStatisticsMap = new HashMap(); // command name --> count + + // private HashMap myStatisticsMap = new HashMap(); // command name --> count + + private final List myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); + + private int myUndoTransparentCount = 0; + + @Override + public void executeCommand(@NotNull Runnable runnable, String name, Object groupId) { + executeCommand(null, runnable, name, groupId); + } + + @Override + public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId) { + executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT); + } + + @Override + public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId, Document document) { + executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT, document); + } + + @Override + public void executeCommand(Project project, + @NotNull final Runnable command, + final String name, + final Object groupId, + @NotNull UndoConfirmationPolicy confirmationPolicy) { + executeCommand(project, command, name, groupId, confirmationPolicy, null); + } + + @Override + public void executeCommand(Project project, + @NotNull final Runnable command, + final String name, + final Object groupId, + @NotNull UndoConfirmationPolicy confirmationPolicy, + Document document) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (project != null && project.isDisposed()) return; + + if (CommandLog.LOG.isDebugEnabled()) { + CommandLog.LOG.debug("executeCommand: " + command + ", name = " + name + ", groupId = " + groupId); + } + + if (myCurrentCommand != null) { + command.run(); + return; + } + Throwable throwable = null; + try { + myCurrentCommand = new CommandDescriptor(command, project, name, groupId, confirmationPolicy, document); + fireCommandStarted(); + command.run(); + } + catch (Throwable th) { + throwable = th; + } + finally { + finishCommand(project, myCurrentCommand, throwable); + } + } + + @Override + @Nullable + public Object startCommand(final Project project, + @Nls final String name, + final Object groupId, + final UndoConfirmationPolicy undoConfirmationPolicy) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (project != null && project.isDisposed()) return null; + + if (CommandLog.LOG.isDebugEnabled()) { + CommandLog.LOG.debug("startCommand: name = " + name + ", groupId = " + groupId); + } + + if (myCurrentCommand != null) { + return null; + } + + Document document = groupId instanceof Ref && ((Ref)groupId).get() instanceof Document ? (Document)((Ref)groupId).get() : null; + myCurrentCommand = new CommandDescriptor(EmptyRunnable.INSTANCE, project, name, groupId, undoConfirmationPolicy, document); + fireCommandStarted(); + return myCurrentCommand; + } + + @Override + public void finishCommand(final Project project, final Object command, final Throwable throwable) { + ApplicationManager.getApplication().assertIsDispatchThread(); + CommandLog.LOG.assertTrue(myCurrentCommand != null, "no current command in progress"); + } + + protected void fireCommandFinished() { + ApplicationManager.getApplication().assertIsDispatchThread(); + CommandDescriptor currentCommand = myCurrentCommand; + CommandEvent event = new CommandEvent(this, currentCommand.myCommand, + currentCommand.myName, + currentCommand.myGroupId, + currentCommand.myProject, + currentCommand.myUndoConfirmationPolicy, + currentCommand.myDocument); + try { + for (CommandListener listener : myListeners) { + try { + listener.beforeCommandFinished(event); + } + catch (Throwable e) { + CommandLog.LOG.error(e); + } + } + } + finally { + myCurrentCommand = null; + for (CommandListener listener : myListeners) { + try { + listener.commandFinished(event); + } + catch (Throwable e) { + CommandLog.LOG.error(e); + } + } + } + } + + @Override + public void enterModal() { + ApplicationManager.getApplication().assertIsDispatchThread(); + CommandDescriptor currentCommand = myCurrentCommand; + myInterruptedCommands.push(currentCommand); + if (currentCommand != null) { + fireCommandFinished(); + } + } + + @Override + public void leaveModal() { + ApplicationManager.getApplication().assertIsDispatchThread(); + CommandLog.LOG.assertTrue(myCurrentCommand == null, "Command must not run: " + String.valueOf(myCurrentCommand)); + + myCurrentCommand = myInterruptedCommands.pop(); + if (myCurrentCommand != null) { + fireCommandStarted(); + } + } + + @Override + public void setCurrentCommandName(String name) { + ApplicationManager.getApplication().assertIsDispatchThread(); + CommandDescriptor currentCommand = myCurrentCommand; + CommandLog.LOG.assertTrue(currentCommand != null); + currentCommand.myName = name; + } + + @Override + public void setCurrentCommandGroupId(Object groupId) { + ApplicationManager.getApplication().assertIsDispatchThread(); + CommandDescriptor currentCommand = myCurrentCommand; + CommandLog.LOG.assertTrue(currentCommand != null); + currentCommand.myGroupId = groupId; + } + + @Override + @Nullable + public Runnable getCurrentCommand() { + CommandDescriptor currentCommand = myCurrentCommand; + return currentCommand != null ? currentCommand.myCommand : null; + } + + @Override + @Nullable + public String getCurrentCommandName() { + CommandDescriptor currentCommand = myCurrentCommand; + if (currentCommand != null) return currentCommand.myName; + if (!myInterruptedCommands.isEmpty()) { + final CommandDescriptor command = myInterruptedCommands.peek(); + return command != null ? command.myName : null; + } + return null; + } + + @Override + @Nullable + public Object getCurrentCommandGroupId() { + CommandDescriptor currentCommand = myCurrentCommand; + if (currentCommand != null) return currentCommand.myGroupId; + if (!myInterruptedCommands.isEmpty()) { + final CommandDescriptor command = myInterruptedCommands.peek(); + return command != null ? command.myGroupId : null; + } + return null; + } + + @Override + @Nullable + public Project getCurrentCommandProject() { + CommandDescriptor currentCommand = myCurrentCommand; + return currentCommand != null ? currentCommand.myProject : null; + } + + @Override + public void addCommandListener(@NotNull CommandListener listener) { + myListeners.add(listener); + } + + @Override + public void addCommandListener(@NotNull final CommandListener listener, @NotNull Disposable parentDisposable) { + addCommandListener(listener); + Disposer.register(parentDisposable, new Disposable() { + @Override + public void dispose() { + removeCommandListener(listener); + } + }); + } + + @Override + public void removeCommandListener(@NotNull CommandListener listener) { + myListeners.remove(listener); + } + + @Override + public void runUndoTransparentAction(@NotNull Runnable action) { + if (myUndoTransparentCount++ == 0) fireUndoTransparentStarted(); + try { + action.run(); + } + finally { + if (--myUndoTransparentCount == 0) fireUndoTransparentFinished(); + } + } + + @Override + public boolean isUndoTransparentActionInProgress() { + return myUndoTransparentCount > 0; + } + + @Override + public void markCurrentCommandAsGlobal(Project project) { + } + + + @Override + public void addAffectedDocuments(Project project, @NotNull Document... docs) { + } + + @Override + public void addAffectedFiles(Project project, @NotNull VirtualFile... files) { + } + + private void fireCommandStarted() { + ApplicationManager.getApplication().assertIsDispatchThread(); + CommandDescriptor currentCommand = myCurrentCommand; + CommandEvent event = new CommandEvent(this, + currentCommand.myCommand, + currentCommand.myName, + currentCommand.myGroupId, + currentCommand.myProject, + currentCommand.myUndoConfirmationPolicy, + currentCommand.myDocument); + for (CommandListener listener : myListeners) { + try { + listener.commandStarted(event); + } + catch (Throwable e) { + CommandLog.LOG.error(e); + } + } + } + + private void fireUndoTransparentStarted() { + for (CommandListener listener : myListeners) { + try { + listener.undoTransparentActionStarted(); + } + catch (Throwable e) { + CommandLog.LOG.error(e); + } + } + } + + private void fireUndoTransparentFinished() { + for (CommandListener listener : myListeners) { + try { + listener.undoTransparentActionFinished(); + } + catch (Throwable e) { + CommandLog.LOG.error(e); + } + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java index c76ee8cd25d2..50cc4e2836fb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -15,149 +15,20 @@ */ package com.intellij.openapi.command.impl; -import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.*; +import com.intellij.openapi.command.AbnormalCommandTerminationException; import com.intellij.openapi.command.undo.UndoManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.EmptyRunnable; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.Stack; - -public class CommandProcessorImpl extends CommandProcessorEx { - private static class CommandDescriptor { - public final Runnable myCommand; - public final Project myProject; - public String myName; - public Object myGroupId; - public final Document myDocument; - public final UndoConfirmationPolicy myUndoConfirmationPolicy; - - public CommandDescriptor(Runnable command, - Project project, - String name, - Object groupId, - UndoConfirmationPolicy undoConfirmationPolicy, - Document document) { - myCommand = command; - myProject = project; - myName = name; - myGroupId = groupId; - myUndoConfirmationPolicy = undoConfirmationPolicy; - myDocument = document; - } - - @Override - public String toString() { - return "'" + myName + "', group: '" + myGroupId + "'"; - } - } - - private CommandDescriptor myCurrentCommand = null; - private final Stack myInterruptedCommands = new Stack(); - -// private HashMap myStatisticsMap = new HashMap(); // command name --> count - - // private HashMap myStatisticsMap = new HashMap(); // command name --> count - - private final List myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); - - private int myUndoTransparentCount = 0; - - @Override - public void executeCommand(@NotNull Runnable runnable, String name, Object groupId) { - executeCommand(null, runnable, name, groupId); - } - - @Override - public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId) { - executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT); - } - - @Override - public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId, Document document) { - executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT, document); - } - - @Override - public void executeCommand(Project project, - @NotNull final Runnable command, - final String name, - final Object groupId, - @NotNull UndoConfirmationPolicy confirmationPolicy) { - executeCommand(project, command, name, groupId, confirmationPolicy, null); - } - - @Override - public void executeCommand(Project project, - @NotNull final Runnable command, - final String name, - final Object groupId, - @NotNull UndoConfirmationPolicy confirmationPolicy, - Document document) { - ApplicationManager.getApplication().assertIsDispatchThread(); - if (project != null && project.isDisposed()) return; - - if (CommandLog.LOG.isDebugEnabled()) { - CommandLog.LOG.debug("executeCommand: " + command + ", name = " + name + ", groupId = " + groupId); - } - - if (myCurrentCommand != null) { - command.run(); - return; - } - Throwable throwable = null; - try { - myCurrentCommand = new CommandDescriptor(command, project, name, groupId, confirmationPolicy, document); - fireCommandStarted(); - command.run(); - } - catch (Throwable th) { - throwable = th; - } - finally { - finishCommand(project, myCurrentCommand, throwable); - } - } - - @Override - @Nullable - public Object startCommand(final Project project, - @Nls final String name, - final Object groupId, - final UndoConfirmationPolicy undoConfirmationPolicy) { - ApplicationManager.getApplication().assertIsDispatchThread(); - if (project != null && project.isDisposed()) return null; - - if (CommandLog.LOG.isDebugEnabled()) { - CommandLog.LOG.debug("startCommand: name = " + name + ", groupId = " + groupId); - } - - if (myCurrentCommand != null) { - return null; - } - - Document document = groupId instanceof Ref && ((Ref)groupId).get() instanceof Document ? (Document)((Ref)groupId).get() : null; - myCurrentCommand = new CommandDescriptor(EmptyRunnable.INSTANCE, project, name, groupId, undoConfirmationPolicy, document); - fireCommandStarted(); - return myCurrentCommand; - } +class CommandProcessorImpl extends CoreCommandProcessor { @Override public void finishCommand(final Project project, final Object command, final Throwable throwable) { - ApplicationManager.getApplication().assertIsDispatchThread(); - CommandLog.LOG.assertTrue(myCurrentCommand != null, "no current command in progress"); + super.finishCommand(project, command, throwable); if (myCurrentCommand != command) return; final boolean failed; try { @@ -195,150 +66,6 @@ public class CommandProcessorImpl extends CommandProcessorEx { } } - private void fireCommandFinished() { - ApplicationManager.getApplication().assertIsDispatchThread(); - CommandDescriptor currentCommand = myCurrentCommand; - CommandEvent event = new CommandEvent(this, currentCommand.myCommand, - currentCommand.myName, - currentCommand.myGroupId, - currentCommand.myProject, - currentCommand.myUndoConfirmationPolicy, - currentCommand.myDocument); - try { - for (CommandListener listener : myListeners) { - try { - listener.beforeCommandFinished(event); - } - catch (Throwable e) { - CommandLog.LOG.error(e); - } - } - } - finally { - myCurrentCommand = null; - for (CommandListener listener : myListeners) { - try { - listener.commandFinished(event); - } - catch (Throwable e) { - CommandLog.LOG.error(e); - } - } - } - } - - @Override - public void enterModal() { - ApplicationManager.getApplication().assertIsDispatchThread(); - CommandDescriptor currentCommand = myCurrentCommand; - myInterruptedCommands.push(currentCommand); - if (currentCommand != null) { - fireCommandFinished(); - } - } - - @Override - public void leaveModal() { - ApplicationManager.getApplication().assertIsDispatchThread(); - CommandLog.LOG.assertTrue(myCurrentCommand == null, "Command must not run: " + String.valueOf(myCurrentCommand)); - - myCurrentCommand = myInterruptedCommands.pop(); - if (myCurrentCommand != null) { - fireCommandStarted(); - } - } - - @Override - public void setCurrentCommandName(String name) { - ApplicationManager.getApplication().assertIsDispatchThread(); - CommandDescriptor currentCommand = myCurrentCommand; - CommandLog.LOG.assertTrue(currentCommand != null); - currentCommand.myName = name; - } - - @Override - public void setCurrentCommandGroupId(Object groupId) { - ApplicationManager.getApplication().assertIsDispatchThread(); - CommandDescriptor currentCommand = myCurrentCommand; - CommandLog.LOG.assertTrue(currentCommand != null); - currentCommand.myGroupId = groupId; - } - - @Override - @Nullable - public Runnable getCurrentCommand() { - CommandDescriptor currentCommand = myCurrentCommand; - return currentCommand != null ? currentCommand.myCommand : null; - } - - @Override - @Nullable - public String getCurrentCommandName() { - CommandDescriptor currentCommand = myCurrentCommand; - if (currentCommand != null) return currentCommand.myName; - if (!myInterruptedCommands.isEmpty()) { - final CommandDescriptor command = myInterruptedCommands.peek(); - return command != null ? command.myName : null; - } - return null; - } - - @Override - @Nullable - public Object getCurrentCommandGroupId() { - CommandDescriptor currentCommand = myCurrentCommand; - if (currentCommand != null) return currentCommand.myGroupId; - if (!myInterruptedCommands.isEmpty()) { - final CommandDescriptor command = myInterruptedCommands.peek(); - return command != null ? command.myGroupId : null; - } - return null; - } - - @Override - @Nullable - public Project getCurrentCommandProject() { - CommandDescriptor currentCommand = myCurrentCommand; - return currentCommand != null ? currentCommand.myProject : null; - } - - @Override - public void addCommandListener(@NotNull CommandListener listener) { - myListeners.add(listener); - } - - @Override - public void addCommandListener(@NotNull final CommandListener listener, @NotNull Disposable parentDisposable) { - addCommandListener(listener); - Disposer.register(parentDisposable, new Disposable() { - @Override - public void dispose() { - removeCommandListener(listener); - } - }); - } - - @Override - public void removeCommandListener(@NotNull CommandListener listener) { - myListeners.remove(listener); - } - - @Override - public void runUndoTransparentAction(@NotNull Runnable action) { - if (myUndoTransparentCount++ == 0) fireUndoTransparentStarted(); - try { - action.run(); - } - finally { - if (--myUndoTransparentCount == 0) fireUndoTransparentFinished(); - } - } - - @Override - public boolean isUndoTransparentActionInProgress() { - return myUndoTransparentCount > 0; - } - @Override public void markCurrentCommandAsGlobal(Project project) { getUndoManager(project).markCurrentCommandAsGlobal(); @@ -357,46 +84,4 @@ public class CommandProcessorImpl extends CommandProcessorEx { public void addAffectedFiles(Project project, @NotNull VirtualFile... files) { getUndoManager(project).addAffectedFiles(files); } - - private void fireCommandStarted() { - ApplicationManager.getApplication().assertIsDispatchThread(); - CommandDescriptor currentCommand = myCurrentCommand; - CommandEvent event = new CommandEvent(this, - currentCommand.myCommand, - currentCommand.myName, - currentCommand.myGroupId, - currentCommand.myProject, - currentCommand.myUndoConfirmationPolicy, - currentCommand.myDocument); - for (CommandListener listener : myListeners) { - try { - listener.commandStarted(event); - } - catch (Throwable e) { - CommandLog.LOG.error(e); - } - } - } - - private void fireUndoTransparentStarted() { - for (CommandListener listener : myListeners) { - try { - listener.undoTransparentActionStarted(); - } - catch (Throwable e) { - CommandLog.LOG.error(e); - } - } - } - - private void fireUndoTransparentFinished() { - for (CommandListener listener : myListeners) { - try { - listener.undoTransparentActionFinished(); - } - catch (Throwable e) { - CommandLog.LOG.error(e); - } - } - } }