From 1a16b48f77d6464527cee8aadc0aae38151058be Mon Sep 17 00:00:00 2001 From: Vassiliy Kudryashov Date: Tue, 17 Jul 2012 19:06:37 +0400 Subject: [PATCH 1/2] Android run configurations cannot be singletons --- .../jetbrains/android/run/AndroidRunConfigurationType.java | 5 +++++ .../android/run/testing/AndroidTestRunConfigurationType.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationType.java b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationType.java index 07c29779bfd7..fcc4a14ac740 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationType.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationType.java @@ -34,6 +34,11 @@ public class AndroidRunConfigurationType implements ConfigurationType { public RunConfiguration createTemplateConfiguration(Project project) { return new AndroidRunConfiguration("", project, this); } + + @Override + public boolean canConfigurationBeSingleton() { + return false; + } }; public static AndroidRunConfigurationType getInstance() { diff --git a/plugins/android/src/org/jetbrains/android/run/testing/AndroidTestRunConfigurationType.java b/plugins/android/src/org/jetbrains/android/run/testing/AndroidTestRunConfigurationType.java index 4d2df95c32ea..afbd7d40367c 100644 --- a/plugins/android/src/org/jetbrains/android/run/testing/AndroidTestRunConfigurationType.java +++ b/plugins/android/src/org/jetbrains/android/run/testing/AndroidTestRunConfigurationType.java @@ -50,6 +50,11 @@ public class AndroidTestRunConfigurationType implements ConfigurationType { public RunConfiguration createTemplateConfiguration(Project project) { return new AndroidTestRunConfiguration("", project, this); } + + @Override + public boolean canConfigurationBeSingleton() { + return false; + } }; public static AndroidTestRunConfigurationType getInstance() { From 0e2bdfe351599ff14b87c61e3a92401c72b811e0 Mon Sep 17 00:00:00 2001 From: Vassiliy Kudryashov Date: Tue, 17 Jul 2012 22:06:56 +0400 Subject: [PATCH 2/2] OC-4615 Rerun ends other debug session --- .../intellij/execution/ExecutionManager.java | 109 +-- .../execution/ExecutorRegistryImpl.java | 518 ++++++------ .../execution/actions/RunContextAction.java | 177 +++-- .../execution/impl/ExecutionManagerImpl.java | 735 +++++++++--------- .../execution/runners/RestartAction.java | 35 +- 5 files changed, 809 insertions(+), 765 deletions(-) diff --git a/platform/lang-api/src/com/intellij/execution/ExecutionManager.java b/platform/lang-api/src/com/intellij/execution/ExecutionManager.java index 9dcb2694f07e..0bf1cb1f91fe 100644 --- a/platform/lang-api/src/com/intellij/execution/ExecutionManager.java +++ b/platform/lang-api/src/com/intellij/execution/ExecutionManager.java @@ -1,54 +1,55 @@ -/* - * 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.execution; - -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.ui.RunContentManager; -import com.intellij.openapi.project.Project; -import com.intellij.util.messages.Topic; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public abstract class ExecutionManager { - public static final Topic EXECUTION_TOPIC - = new Topic("configuration executed", ExecutionListener.class, Topic.BroadcastDirection.TO_PARENT); - - public static ExecutionManager getInstance(final Project project) { - return project.getComponent(ExecutionManager.class); - } - - public abstract RunContentManager getContentManager(); - - public abstract void compileAndRun(@NotNull Runnable startRunnable, - @NotNull ExecutionEnvironment env, - @Nullable RunProfileState state, - @Nullable Runnable onCancelRunnable); - - public abstract ProcessHandler[] getRunningProcesses(); - - public abstract void startRunProfile(@NotNull RunProfileStarter starter, - @NotNull RunProfileState state, - @NotNull Project project, - @NotNull Executor executor, - @NotNull ExecutionEnvironment env); - - public abstract void restartRunProfile(@NotNull Project project, - @NotNull Executor executor, - @NotNull ExecutionTarget target, - @NotNull RunnerAndConfigurationSettings configuration); -} +/* + * 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.execution; + +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.ui.RunContentManager; +import com.intellij.openapi.project.Project; +import com.intellij.util.messages.Topic; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class ExecutionManager { + public static final Topic EXECUTION_TOPIC + = new Topic("configuration executed", ExecutionListener.class, Topic.BroadcastDirection.TO_PARENT); + + public static ExecutionManager getInstance(final Project project) { + return project.getComponent(ExecutionManager.class); + } + + public abstract RunContentManager getContentManager(); + + public abstract void compileAndRun(@NotNull Runnable startRunnable, + @NotNull ExecutionEnvironment env, + @Nullable RunProfileState state, + @Nullable Runnable onCancelRunnable); + + public abstract ProcessHandler[] getRunningProcesses(); + + public abstract void startRunProfile(@NotNull RunProfileStarter starter, + @NotNull RunProfileState state, + @NotNull Project project, + @NotNull Executor executor, + @NotNull ExecutionEnvironment env); + + public abstract void restartRunProfile(@NotNull Project project, + @NotNull Executor executor, + @NotNull ExecutionTarget target, + @NotNull RunnerAndConfigurationSettings configuration, + @Nullable ProcessHandler processHandler); +} diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java index b411ac6ecf31..4bbd6427c547 100644 --- a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java @@ -1,259 +1,259 @@ -/* - * 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.execution; - -import com.intellij.execution.actions.RunContextAction; -import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.ProgramRunner; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.project.*; -import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.util.Trinity; -import com.intellij.util.containers.HashMap; -import com.intellij.util.containers.HashSet; -import com.intellij.util.messages.MessageBusConnection; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.util.*; - -/** - * @author spleaner - */ -public class ExecutorRegistryImpl extends ExecutorRegistry { - private static final Logger LOG = Logger.getInstance("#com.intellij.execution.ExecutorRegistryImpl"); - private static final Icon STOP_AND_START_ICON = IconLoader.getIcon("/actions/restart.png"); - - - @NonNls public static final String RUNNERS_GROUP = "RunnerActions"; - @NonNls public static final String RUN_CONTEXT_GROUP = "RunContextGroup"; - - private List myExecutors = new ArrayList(); - private ActionManager myActionManager; - private final Map myId2Executor = new HashMap(); - private final Set myContextActionIdSet = new HashSet(); - private final Map myId2Action = new HashMap(); - private final Map myContextActionId2Action = new HashMap(); - - // [Project, ExecutorId, RunnerId] - private final Set> myInProgress = Collections.synchronizedSet(new java.util.HashSet>()); - - public ExecutorRegistryImpl(ActionManager actionManager) { - myActionManager = actionManager; - } - - synchronized void initExecutor(@NotNull final Executor executor) { - if (myId2Executor.get(executor.getId()) != null) { - LOG.error("Executor with id: \"" + executor.getId() + "\" was already registered!"); - } - - if (myContextActionIdSet.contains(executor.getContextActionId())) { - LOG.error("Executor with context action id: \"" + executor.getContextActionId() + "\" was already registered!"); - } - - myExecutors.add(executor); - myId2Executor.put(executor.getId(), executor); - myContextActionIdSet.add(executor.getContextActionId()); - - registerAction(executor.getId(), new ExecutorAction(executor), RUNNERS_GROUP, myId2Action); - registerAction(executor.getContextActionId(), new RunContextAction(executor), RUN_CONTEXT_GROUP, myContextActionId2Action); - } - - private void registerAction(@NotNull final String actionId, @NotNull final AnAction anAction, @NotNull final String groupId, @NotNull final Map map) { - AnAction action = myActionManager.getAction(actionId); - if (action == null) { - myActionManager.registerAction(actionId, anAction); - map.put(actionId, anAction); - action = anAction; - } - - final DefaultActionGroup group = (DefaultActionGroup) myActionManager.getAction(groupId); - group.add(action); - } - - synchronized void deinitExecutor(@NotNull final Executor executor) { - myExecutors.remove(executor); - myId2Executor.remove(executor.getId()); - myContextActionIdSet.remove(executor.getContextActionId()); - - unregisterAction(executor.getId(), RUNNERS_GROUP, myId2Action); - unregisterAction(executor.getContextActionId(), RUN_CONTEXT_GROUP, myContextActionId2Action); - } - - private void unregisterAction(@NotNull final String actionId, @NotNull final String groupId, @NotNull final Map map) { - final DefaultActionGroup group = (DefaultActionGroup)myActionManager.getAction(groupId); - if (group != null) { - group.remove(myActionManager.getAction(actionId)); - final AnAction action = map.get(actionId); - if (action != null) { - myActionManager.unregisterAction(actionId); - map.remove(actionId); - } - } - } - - @NotNull - public synchronized Executor[] getRegisteredExecutors() { - return myExecutors.toArray(new Executor[myExecutors.size()]); - } - - public Executor getExecutorById(final String executorId) { - return myId2Executor.get(executorId); - } - - @NonNls - @NotNull - public String getComponentName() { - return "ExecutorRegistyImpl"; - } - - public void initComponent() { - ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() { - public void projectOpened(final Project project) { - final MessageBusConnection connect = project.getMessageBus().connect(project); - connect.subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter(){ - public void processStartScheduled(String executorId, ExecutionEnvironment env) { - myInProgress.add(createExecutionId(executorId, env, project)); - } - - public void processNotStarted(String executorId, @NotNull ExecutionEnvironment env) { - myInProgress.remove(createExecutionId(executorId, env, project)); - } - - public void processStarted(String executorId, @NotNull ExecutionEnvironment env, @NotNull ProcessHandler handler) { - myInProgress.remove(createExecutionId(executorId, env, project)); - } - }); - } - - @Override - public void projectClosed(final Project project) { - // perform cleanup - synchronized (myInProgress) { - for (Iterator> it = myInProgress.iterator(); it.hasNext(); ) { - final Trinity trinity = it.next(); - if (project.equals(trinity.first)) { - it.remove(); - } - } - } - } - }); - - - final Executor[] executors = Extensions.getExtensions(Executor.EXECUTOR_EXTENSION_NAME); - for (Executor executor : executors) { - initExecutor(executor); - } - } - - private static Trinity createExecutionId(String executorId, ExecutionEnvironment env, Project project) { - final ConfigurationPerRunnerSettings settings = env.getConfigurationSettings(); - return new Trinity(project, executorId, settings != null? settings.getRunnerId() : null); - } - - public boolean isStarting(Project project, final String executorId, final String runnerId) { - return myInProgress.contains(new Trinity(project, executorId, runnerId)); - } - - public synchronized void disposeComponent() { - if (myExecutors.size() > 0) { - List executors = new ArrayList(myExecutors); - for (Executor executor : executors) { - deinitExecutor(executor); - } - - myExecutors = null; - } - - myActionManager = null; - } - - private class ExecutorAction extends AnAction implements DumbAware { - private final Executor myExecutor; - - private ExecutorAction(@NotNull final Executor executor) { - super(executor.getStartActionText(), executor.getActionName(), executor.getIcon()); - myExecutor = executor; - } - - public void update(final AnActionEvent e) { - super.update(e); - - final Presentation presentation = e.getPresentation(); - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); - - if (project == null || !project.isInitialized() || project.isDisposed() || DumbService.getInstance(project).isDumb()) { - presentation.setEnabled(false); - return; - } - - final RunnerAndConfigurationSettings selectedConfiguration = getConfiguration(project); - boolean enabled = false; - String text; - final String textWithMnemonic = getTemplatePresentation().getTextWithMnemonic(); - if (selectedConfiguration != null) { - final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(myExecutor.getId(), selectedConfiguration.getConfiguration()); - - ExecutionTarget target = ExecutionTargetManager.getActiveTarget(project); - enabled = ExecutionTargetManager.canRun(selectedConfiguration, target) - && runner != null && !isStarting(project, myExecutor.getId(), runner.getRunnerId()); - - if (enabled) { - presentation.setDescription(myExecutor.getDescription()); - } - text = myExecutor.getStartActionText(selectedConfiguration.getName()); - } - else { - text = textWithMnemonic; - } - - presentation.setEnabled(enabled); - presentation.setText(text); - } - - @Nullable - private RunnerAndConfigurationSettings getConfiguration(@NotNull final Project project) { - return RunManagerEx.getInstanceEx(project).getSelectedConfiguration(); - } - - public void actionPerformed(final AnActionEvent e) { - final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null || project.isDisposed()) { - return; - } - final RunnerAndConfigurationSettings configuration = getConfiguration(project); - if (configuration == null) { - return; - } - - ExecutionTarget target = ExecutionTargetManager.getActiveTarget(project); - if (configuration.isSingleton()) { - ExecutionManager.getInstance(project).restartRunProfile(project, myExecutor, target, configuration); - } else { - ProgramRunnerUtil.executeConfiguration(project, configuration, myExecutor, target); - } - } - } -} +/* + * 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.execution; + +import com.intellij.execution.actions.RunContextAction; +import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunContentManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.*; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Trinity; +import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.HashSet; +import com.intellij.util.messages.MessageBusConnection; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.*; + +/** + * @author spleaner + */ +public class ExecutorRegistryImpl extends ExecutorRegistry { + private static final Logger LOG = Logger.getInstance("#com.intellij.execution.ExecutorRegistryImpl"); + private static final Icon STOP_AND_START_ICON = IconLoader.getIcon("/actions/restart.png"); + + + @NonNls public static final String RUNNERS_GROUP = "RunnerActions"; + @NonNls public static final String RUN_CONTEXT_GROUP = "RunContextGroup"; + + private List myExecutors = new ArrayList(); + private ActionManager myActionManager; + private final Map myId2Executor = new HashMap(); + private final Set myContextActionIdSet = new HashSet(); + private final Map myId2Action = new HashMap(); + private final Map myContextActionId2Action = new HashMap(); + + // [Project, ExecutorId, RunnerId] + private final Set> myInProgress = Collections.synchronizedSet(new java.util.HashSet>()); + + public ExecutorRegistryImpl(ActionManager actionManager) { + myActionManager = actionManager; + } + + synchronized void initExecutor(@NotNull final Executor executor) { + if (myId2Executor.get(executor.getId()) != null) { + LOG.error("Executor with id: \"" + executor.getId() + "\" was already registered!"); + } + + if (myContextActionIdSet.contains(executor.getContextActionId())) { + LOG.error("Executor with context action id: \"" + executor.getContextActionId() + "\" was already registered!"); + } + + myExecutors.add(executor); + myId2Executor.put(executor.getId(), executor); + myContextActionIdSet.add(executor.getContextActionId()); + + registerAction(executor.getId(), new ExecutorAction(executor), RUNNERS_GROUP, myId2Action); + registerAction(executor.getContextActionId(), new RunContextAction(executor), RUN_CONTEXT_GROUP, myContextActionId2Action); + } + + private void registerAction(@NotNull final String actionId, @NotNull final AnAction anAction, @NotNull final String groupId, @NotNull final Map map) { + AnAction action = myActionManager.getAction(actionId); + if (action == null) { + myActionManager.registerAction(actionId, anAction); + map.put(actionId, anAction); + action = anAction; + } + + final DefaultActionGroup group = (DefaultActionGroup) myActionManager.getAction(groupId); + group.add(action); + } + + synchronized void deinitExecutor(@NotNull final Executor executor) { + myExecutors.remove(executor); + myId2Executor.remove(executor.getId()); + myContextActionIdSet.remove(executor.getContextActionId()); + + unregisterAction(executor.getId(), RUNNERS_GROUP, myId2Action); + unregisterAction(executor.getContextActionId(), RUN_CONTEXT_GROUP, myContextActionId2Action); + } + + private void unregisterAction(@NotNull final String actionId, @NotNull final String groupId, @NotNull final Map map) { + final DefaultActionGroup group = (DefaultActionGroup)myActionManager.getAction(groupId); + if (group != null) { + group.remove(myActionManager.getAction(actionId)); + final AnAction action = map.get(actionId); + if (action != null) { + myActionManager.unregisterAction(actionId); + map.remove(actionId); + } + } + } + + @NotNull + public synchronized Executor[] getRegisteredExecutors() { + return myExecutors.toArray(new Executor[myExecutors.size()]); + } + + public Executor getExecutorById(final String executorId) { + return myId2Executor.get(executorId); + } + + @NonNls + @NotNull + public String getComponentName() { + return "ExecutorRegistyImpl"; + } + + public void initComponent() { + ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() { + public void projectOpened(final Project project) { + final MessageBusConnection connect = project.getMessageBus().connect(project); + connect.subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter(){ + public void processStartScheduled(String executorId, ExecutionEnvironment env) { + myInProgress.add(createExecutionId(executorId, env, project)); + } + + public void processNotStarted(String executorId, @NotNull ExecutionEnvironment env) { + myInProgress.remove(createExecutionId(executorId, env, project)); + } + + public void processStarted(String executorId, @NotNull ExecutionEnvironment env, @NotNull ProcessHandler handler) { + myInProgress.remove(createExecutionId(executorId, env, project)); + } + }); + } + + @Override + public void projectClosed(final Project project) { + // perform cleanup + synchronized (myInProgress) { + for (Iterator> it = myInProgress.iterator(); it.hasNext(); ) { + final Trinity trinity = it.next(); + if (project.equals(trinity.first)) { + it.remove(); + } + } + } + } + }); + + + final Executor[] executors = Extensions.getExtensions(Executor.EXECUTOR_EXTENSION_NAME); + for (Executor executor : executors) { + initExecutor(executor); + } + } + + private static Trinity createExecutionId(String executorId, ExecutionEnvironment env, Project project) { + final ConfigurationPerRunnerSettings settings = env.getConfigurationSettings(); + return new Trinity(project, executorId, settings != null? settings.getRunnerId() : null); + } + + public boolean isStarting(Project project, final String executorId, final String runnerId) { + return myInProgress.contains(new Trinity(project, executorId, runnerId)); + } + + public synchronized void disposeComponent() { + if (myExecutors.size() > 0) { + List executors = new ArrayList(myExecutors); + for (Executor executor : executors) { + deinitExecutor(executor); + } + + myExecutors = null; + } + + myActionManager = null; + } + + private class ExecutorAction extends AnAction implements DumbAware { + private final Executor myExecutor; + + private ExecutorAction(@NotNull final Executor executor) { + super(executor.getStartActionText(), executor.getActionName(), executor.getIcon()); + myExecutor = executor; + } + + public void update(final AnActionEvent e) { + super.update(e); + + final Presentation presentation = e.getPresentation(); + final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + + if (project == null || !project.isInitialized() || project.isDisposed() || DumbService.getInstance(project).isDumb()) { + presentation.setEnabled(false); + return; + } + + final RunnerAndConfigurationSettings selectedConfiguration = getConfiguration(project); + boolean enabled = false; + String text; + final String textWithMnemonic = getTemplatePresentation().getTextWithMnemonic(); + if (selectedConfiguration != null) { + final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(myExecutor.getId(), selectedConfiguration.getConfiguration()); + + ExecutionTarget target = ExecutionTargetManager.getActiveTarget(project); + enabled = ExecutionTargetManager.canRun(selectedConfiguration, target) + && runner != null && !isStarting(project, myExecutor.getId(), runner.getRunnerId()); + + if (enabled) { + presentation.setDescription(myExecutor.getDescription()); + } + text = myExecutor.getStartActionText(selectedConfiguration.getName()); + } + else { + text = textWithMnemonic; + } + + presentation.setEnabled(enabled); + presentation.setText(text); + } + + @Nullable + private RunnerAndConfigurationSettings getConfiguration(@NotNull final Project project) { + return RunManagerEx.getInstanceEx(project).getSelectedConfiguration(); + } + + public void actionPerformed(final AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + if (project == null || project.isDisposed()) { + return; + } + final RunnerAndConfigurationSettings configuration = getConfiguration(project); + if (configuration == null) { + return; + } + + ExecutionTarget target = ExecutionTargetManager.getActiveTarget(project); + RunContentDescriptor runContentDescriptor = RunContentManager.RUN_CONTENT_DESCRIPTOR.getData(dataContext); + ProcessHandler processHandler = runContentDescriptor != null ? runContentDescriptor.getProcessHandler(): null; + ExecutionManager.getInstance(project).restartRunProfile(project, myExecutor, target, configuration, processHandler); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/actions/RunContextAction.java b/platform/lang-impl/src/com/intellij/execution/actions/RunContextAction.java index 34b2654adf76..979de1eec8f8 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/RunContextAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/RunContextAction.java @@ -1,83 +1,94 @@ -/* - * 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.execution.actions; - -import com.intellij.execution.*; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.runners.ProgramRunner; -import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.openapi.util.Pair; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class RunContextAction extends BaseRunConfigurationAction { - private final Executor myExecutor; - - public RunContextAction(@NotNull final Executor executor) { - super(ExecutionBundle.message("perform.action.with.context.configuration.action.name", executor.getStartActionText()), null, - executor.getIcon()); - myExecutor = executor; - } - - protected void perform(final ConfigurationContext context) { - RunnerAndConfigurationSettings configuration = context.findExisting(); - final RunManagerEx runManager = (RunManagerEx)context.getRunManager(); - if (configuration == null) { - configuration = context.getConfiguration(); - if (configuration == null) { - return; - } - runManager.setTemporaryConfiguration(configuration); - } - runManager.setActiveConfiguration(configuration); - - ProgramRunnerUtil.executeConfiguration(context.getProject(), configuration, myExecutor); - } - - @Override - protected boolean isEnabledFor(RunConfiguration configuration) { - return getRunner(configuration) != null; - } - - @Nullable - private ProgramRunner getRunner(final RunConfiguration configuration) { - return RunnerRegistry.getInstance().getRunner(myExecutor.getId(), configuration); - } - - protected void updatePresentation(final Presentation presentation, final String actionText, final ConfigurationContext context) { - presentation.setText(myExecutor.getStartActionText(actionText), true); - - Pair b = isEnabledAndVisible(context); - - presentation.setEnabled(b.first); - presentation.setVisible(b.second); - } - - private Pair isEnabledAndVisible(ConfigurationContext context) { - RunnerAndConfigurationSettings configuration = context.findExisting(); - if (configuration == null) { - configuration = context.getConfiguration(); - } - - if (configuration == null) return Pair.create(false, false); - - final ProgramRunner runner = getRunner(configuration.getConfiguration()); - if (runner == null) return Pair.create(false, false); - - return Pair.create(!ExecutorRegistry.getInstance().isStarting(context.getProject(), myExecutor.getId(), runner.getRunnerId()), true); - } -} +/* + * 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.execution.actions; + +import com.intellij.execution.*; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class RunContextAction extends BaseRunConfigurationAction { + private final Executor myExecutor; + + public RunContextAction(@NotNull final Executor executor) { + super(ExecutionBundle.message("perform.action.with.context.configuration.action.name", executor.getStartActionText()), null, + executor.getIcon()); + myExecutor = executor; + } + + protected void perform(final ConfigurationContext context) { + RunnerAndConfigurationSettings configuration = context.findExisting(); + final RunManagerEx runManager = (RunManagerEx)context.getRunManager(); + if (configuration == null) { + configuration = context.getConfiguration(); + if (configuration == null) { + return; + } + runManager.setTemporaryConfiguration(configuration); + } + runManager.setSelectedConfiguration(configuration); + Project project = context.getProject(); + if (configuration.isSingleton()) { + ExecutionTarget activeTarget = ExecutionTargetManager.getActiveTarget(project); + ExecutionManager.getInstance(project).restartRunProfile(project, + myExecutor, + activeTarget, + configuration, + null); + } else + { + ProgramRunnerUtil.executeConfiguration(project, configuration, myExecutor); + } + } + + @Override + protected boolean isEnabledFor(RunConfiguration configuration) { + return getRunner(configuration) != null; + } + + @Nullable + private ProgramRunner getRunner(final RunConfiguration configuration) { + return RunnerRegistry.getInstance().getRunner(myExecutor.getId(), configuration); + } + + protected void updatePresentation(final Presentation presentation, final String actionText, final ConfigurationContext context) { + presentation.setText(myExecutor.getStartActionText(actionText), true); + + Pair b = isEnabledAndVisible(context); + + presentation.setEnabled(b.first); + presentation.setVisible(b.second); + } + + private Pair isEnabledAndVisible(ConfigurationContext context) { + RunnerAndConfigurationSettings configuration = context.findExisting(); + if (configuration == null) { + configuration = context.getConfiguration(); + } + + if (configuration == null) return Pair.create(false, false); + + final ProgramRunner runner = getRunner(configuration.getConfiguration()); + if (runner == null) return Pair.create(false, false); + + return Pair.create(!ExecutorRegistry.getInstance().isStarting(context.getProject(), myExecutor.getId(), runner.getRunnerId()), true); + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java index 84b6313cfaa5..7141a4da1ef7 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java @@ -1,353 +1,382 @@ -/* - * 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.execution.impl; - -import com.intellij.CommonBundle; -import com.intellij.execution.*; -import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.configurations.RunProfile; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.process.ProcessAdapter; -import com.intellij.execution.process.ProcessEvent; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.ExecutionUtil; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.execution.ui.RunContentManager; -import com.intellij.execution.ui.RunContentManagerImpl; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.impl.SimpleDataContext; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.ProjectComponent; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.Trinity; -import com.intellij.ui.docking.DockManager; -import com.intellij.util.Alarm; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * @author dyoma - */ -public class ExecutionManagerImpl extends ExecutionManager implements ProjectComponent { - private static final Logger LOG = Logger.getInstance("com.intellij.execution.impl.ExecutionManagerImpl"); - - private final Project myProject; - - private RunContentManagerImpl myContentManager; - private final Alarm awaitingTerminationAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); - private final List> myRunningConfigurations = - new ArrayList>(); - - /** - * reflection - */ - ExecutionManagerImpl(final Project project) { - myProject = project; - } - - public void projectOpened() { - ((RunContentManagerImpl)getContentManager()).init(); - } - - public void projectClosed() { - } - - public void initComponent() { - } - - public void disposeComponent() { - } - - public RunContentManager getContentManager() { - if (myContentManager == null) { - myContentManager = new RunContentManagerImpl(myProject, DockManager.getInstance(myProject)); - Disposer.register(myProject, myContentManager); - } - return myContentManager; - } - - public ProcessHandler[] getRunningProcesses() { - final List handlers = new ArrayList(); - for (RunContentDescriptor descriptor : getContentManager().getAllDescriptors()) { - final ProcessHandler processHandler = descriptor.getProcessHandler(); - if (processHandler != null) { - handlers.add(processHandler); - } - } - return handlers.toArray(new ProcessHandler[handlers.size()]); - } - - public void compileAndRun(@NotNull final Runnable startRunnable, @NotNull final ExecutionEnvironment env, final @Nullable RunProfileState state, @Nullable final Runnable onCancelRunnable) { - RunProfile profile = env.getRunProfile(); - - if (profile instanceof RunConfiguration) { - final RunConfiguration runConfiguration = (RunConfiguration)profile; - final RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(myProject); - - final List activeTasks = new ArrayList(); - activeTasks.addAll(runManager.getBeforeRunTasks(runConfiguration)); - - ConfigurationPerRunnerSettings configurationSettings = state != null ? state.getConfigurationSettings() : null; - final DataContext projectContext = SimpleDataContext.getProjectContext(myProject); - final DataContext dataContext = configurationSettings != null ? SimpleDataContext - .getSimpleContext(BeforeRunTaskProvider.RUNNER_ID, configurationSettings.getRunnerId(), projectContext) : projectContext; - - if (!activeTasks.isEmpty()) { - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - /** @noinspection SSBasedInspection*/ - public void run() { - for (BeforeRunTask task : activeTasks) { - BeforeRunTaskProvider provider = BeforeRunTaskProvider.getProvider(myProject, task.getProviderId()); - if(provider != null && !provider.executeTask(dataContext, runConfiguration, env, task)) { - if (onCancelRunnable != null) { - SwingUtilities.invokeLater(onCancelRunnable); - } - return; - } - } - // important! Do not use DumbService.smartInvokelater here because it depends on modality state - // and execution of startRunnable could be skipped if modality state check fails - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - if (!myProject.isDisposed()) { - DumbService.getInstance(myProject).runWhenSmart(startRunnable); - } - } - }); - } - }); - } - else { - startRunnable.run(); - } - } - else { - startRunnable.run(); - } - } - - @Override - public void startRunProfile(@NotNull final RunProfileStarter starter, @NotNull final RunProfileState state, - @NotNull final Project project, @NotNull final Executor executor, @NotNull final ExecutionEnvironment env) { - final RunContentDescriptor reuseContent = ExecutionManager.getInstance(project).getContentManager().getReuseContent(executor, env.getContentToReuse()); - final RunProfile profile = env.getRunProfile(); - - project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStartScheduled(executor.getId(), env); - - Runnable startRunnable = new Runnable() { - public void run() { - if (project.isDisposed()) return; - boolean started = false; - try { - project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarting(executor.getId(), env); - - final RunContentDescriptor descriptor = starter.execute(project, executor, state, reuseContent, env); - - if (descriptor != null) { - myRunningConfigurations.add(Trinity.create(descriptor, env.getRunnerAndConfigurationSettings(), executor)); - ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor, reuseContent); - final ProcessHandler processHandler = descriptor.getProcessHandler(); - if (processHandler != null) { - processHandler.startNotify(); - project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarted(executor.getId(), env, processHandler); - started = true; - processHandler.addProcessListener(new ProcessExecutionListener(project, profile, processHandler)); - } - } - } - catch (ExecutionException e) { - ExecutionUtil.handleExecutionError(project, executor.getToolWindowId(), profile, e); - LOG.info(e); - } - finally { - if (!started) { - project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(executor.getId(), env); - } - } - } - }; - - if (ApplicationManager.getApplication().isUnitTestMode()) { - startRunnable.run(); - } - else { - compileAndRun(startRunnable, env, state, new Runnable() { - public void run() { - if (!project.isDisposed()) { - project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(executor.getId(), env); - } - } - }); - } - } - - @Override - public void restartRunProfile(@NotNull final Project project, - @NotNull final Executor executor, - @NotNull final ExecutionTarget target, - @NotNull final RunnerAndConfigurationSettings configuration) { - RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(project); - final RunManagerConfig config = runManager.getConfig(); - final List> pairs = getRunningDescriptors(configuration); - - for (Pair pair : pairs) { - ProcessHandler processHandler = pair.getFirst().getProcessHandler(); - if (processHandler == null) - continue; - if (!processHandler.isProcessTerminated()) { - if (config.isRestartRequiresConfirmation()) { - DialogWrapper.DoNotAskOption option = new DialogWrapper.DoNotAskOption() { - @Override - public boolean isToBeShown() { - return config.isRestartRequiresConfirmation(); - } - - @Override - public void setToBeShown(boolean value, int exitCode) { - config.setRestartRequiresConfirmation(value); - } /**/ - - @Override - public boolean canBeHidden() { - return true; - } - - @Override - public boolean shouldSaveOptionsOnCancel() { - return false; - } - - @Override - public String getDoNotShowMessage() { - return CommonBundle.message("dialog.options.do.not.show"); - } - }; - if (Messages.OK != Messages.showOkCancelDialog(ExecutionBundle.message("rerun.confirmation.message", configuration.getName()), - ExecutionBundle.message("rerun.confirmation.title") + " ("+pair.getSecond().getId()+")", - CommonBundle.message("button.ok"), - CommonBundle.message("button.cancel"), - Messages.getQuestionIcon(), option)) { - return; - } - } - stop(processHandler); - for ( - Iterator> iterator = myRunningConfigurations.iterator(); - iterator.hasNext(); ) { - Trinity trinity = iterator.next(); - if (trinity.getFirst() == pair.getFirst()) { - iterator.remove(); - break; - } - } - } - } - - if (pairs.isEmpty()) { - ProgramRunnerUtil.executeConfiguration(project, configuration, executor, target); - return; - } - - Runnable runnable = new Runnable() { - @Override - public void run() { - for (Pair pair : pairs) { - ProcessHandler processHandler = pair.getFirst().getProcessHandler(); - if (processHandler == null) - continue; - if (!processHandler.isProcessTerminated()) { - awaitingTerminationAlarm.addRequest(this, 100); - return; - } - } - ProgramRunnerUtil.executeConfiguration(project, configuration, executor, target); - } - }; - awaitingTerminationAlarm.addRequest(runnable, 100); - } - - private List> getRunningDescriptors(RunnerAndConfigurationSettings configuration) { - List> result = new ArrayList>(); - for (Trinity trinity : myRunningConfigurations) { - if (trinity.getSecond() == configuration) { - result.add(Pair.create(trinity.getFirst(), trinity.getThird())); - } - } - return result; - } - - - - private static void stop(ProcessHandler processHandler) { - if (processHandler instanceof KillableProcess && processHandler.isProcessTerminating()) { - ((KillableProcess)processHandler).killProcess(); - return; - } - - if (processHandler.detachIsDefault()) { - processHandler.detachProcess(); - } - else { - processHandler.destroyProcess(); - } - } - - @NotNull - public String getComponentName() { - return "ExecutionManager"; - } - - private static class ProcessExecutionListener extends ProcessAdapter { - private final Project myProject; - private final RunProfile myProfile; - private final ProcessHandler myProcessHandler; - - public ProcessExecutionListener(Project project, RunProfile profile, ProcessHandler processHandler) { - myProject = project; - myProfile = profile; - myProcessHandler = processHandler; - } - - @Override - public void processTerminated(ProcessEvent event) { - if (myProject.isDisposed()) return; - - myProject.getMessageBus().syncPublisher(EXECUTION_TOPIC).processTerminated(myProfile, myProcessHandler); - } - - @Override - public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) { - if (myProject.isDisposed()) return; - - myProject.getMessageBus().syncPublisher(EXECUTION_TOPIC).processTerminating(myProfile, myProcessHandler); - } - } -} +/* + * 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.execution.impl; + +import com.intellij.CommonBundle; +import com.intellij.execution.*; +import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ExecutionUtil; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunContentManager; +import com.intellij.execution.ui.RunContentManagerImpl; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.impl.SimpleDataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Trinity; +import com.intellij.ui.docking.DockManager; +import com.intellij.util.Alarm; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author dyoma + */ +public class ExecutionManagerImpl extends ExecutionManager implements ProjectComponent { + private static final Logger LOG = Logger.getInstance("com.intellij.execution.impl.ExecutionManagerImpl"); + + private final Project myProject; + + private RunContentManagerImpl myContentManager; + private final Alarm awaitingTerminationAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + private final List> myRunningConfigurations = + new ArrayList>(); + + /** + * reflection + */ + ExecutionManagerImpl(final Project project) { + myProject = project; + } + + public void projectOpened() { + ((RunContentManagerImpl)getContentManager()).init(); + } + + public void projectClosed() { + } + + public void initComponent() { + } + + public void disposeComponent() { + } + + public RunContentManager getContentManager() { + if (myContentManager == null) { + myContentManager = new RunContentManagerImpl(myProject, DockManager.getInstance(myProject)); + Disposer.register(myProject, myContentManager); + } + return myContentManager; + } + + public ProcessHandler[] getRunningProcesses() { + final List handlers = new ArrayList(); + for (RunContentDescriptor descriptor : getContentManager().getAllDescriptors()) { + final ProcessHandler processHandler = descriptor.getProcessHandler(); + if (processHandler != null) { + handlers.add(processHandler); + } + } + return handlers.toArray(new ProcessHandler[handlers.size()]); + } + + public void compileAndRun(@NotNull final Runnable startRunnable, + @NotNull final ExecutionEnvironment env, + final @Nullable RunProfileState state, + @Nullable final Runnable onCancelRunnable) { + RunProfile profile = env.getRunProfile(); + + if (profile instanceof RunConfiguration) { + final RunConfiguration runConfiguration = (RunConfiguration)profile; + final RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(myProject); + + final List activeTasks = new ArrayList(); + activeTasks.addAll(runManager.getBeforeRunTasks(runConfiguration)); + + ConfigurationPerRunnerSettings configurationSettings = state != null ? state.getConfigurationSettings() : null; + final DataContext projectContext = SimpleDataContext.getProjectContext(myProject); + final DataContext dataContext = configurationSettings != null ? SimpleDataContext + .getSimpleContext(BeforeRunTaskProvider.RUNNER_ID, configurationSettings.getRunnerId(), projectContext) : projectContext; + + if (!activeTasks.isEmpty()) { + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + /** @noinspection SSBasedInspection*/ + public void run() { + for (BeforeRunTask task : activeTasks) { + BeforeRunTaskProvider provider = BeforeRunTaskProvider.getProvider(myProject, task.getProviderId()); + if (provider != null && !provider.executeTask(dataContext, runConfiguration, env, task)) { + if (onCancelRunnable != null) { + SwingUtilities.invokeLater(onCancelRunnable); + } + return; + } + } + // important! Do not use DumbService.smartInvokelater here because it depends on modality state + // and execution of startRunnable could be skipped if modality state check fails + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (!myProject.isDisposed()) { + DumbService.getInstance(myProject).runWhenSmart(startRunnable); + } + } + }); + } + }); + } + else { + startRunnable.run(); + } + } + else { + startRunnable.run(); + } + } + + @Override + public void startRunProfile(@NotNull final RunProfileStarter starter, @NotNull final RunProfileState state, + @NotNull final Project project, @NotNull final Executor executor, @NotNull final ExecutionEnvironment env) { + final RunContentDescriptor reuseContent = + ExecutionManager.getInstance(project).getContentManager().getReuseContent(executor, env.getContentToReuse()); + final RunProfile profile = env.getRunProfile(); + + project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStartScheduled(executor.getId(), env); + + Runnable startRunnable = new Runnable() { + public void run() { + if (project.isDisposed()) return; + boolean started = false; + try { + project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarting(executor.getId(), env); + + final RunContentDescriptor descriptor = starter.execute(project, executor, state, reuseContent, env); + + if (descriptor != null) { + myRunningConfigurations.add(Trinity.create(descriptor, env.getRunnerAndConfigurationSettings(), executor)); + ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor, reuseContent); + final ProcessHandler processHandler = descriptor.getProcessHandler(); + if (processHandler != null) { + processHandler.startNotify(); + project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarted(executor.getId(), env, processHandler); + started = true; + processHandler.addProcessListener(new ProcessExecutionListener(project, profile, processHandler)); + } + } + } + catch (ExecutionException e) { + ExecutionUtil.handleExecutionError(project, executor.getToolWindowId(), profile, e); + LOG.info(e); + } + finally { + if (!started) { + project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(executor.getId(), env); + } + } + } + }; + + if (ApplicationManager.getApplication().isUnitTestMode()) { + startRunnable.run(); + } + else { + compileAndRun(startRunnable, env, state, new Runnable() { + public void run() { + if (!project.isDisposed()) { + project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(executor.getId(), env); + } + } + }); + } + } + + @Override + public void restartRunProfile(@NotNull final Project project, + @NotNull final Executor executor, + @NotNull final ExecutionTarget target, + @NotNull final RunnerAndConfigurationSettings configuration, + @Nullable final ProcessHandler handler) { + RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(project); + final RunManagerConfig config = runManager.getConfig(); + final List allHandlers = new ArrayList(); + final List handlersToStop = new ArrayList(); + final List> pairs = getRunningDescriptors(configuration); + if (configuration.isSingleton()) { + for (Pair pair : pairs) { + allHandlers.add(pair.getFirst().getProcessHandler()); + } + } + else if (handler != null) { + allHandlers.add(handler); + } + + if (!allHandlers.isEmpty()) { + for (Pair pair : pairs) { + ProcessHandler processHandler = pair.getFirst().getProcessHandler(); + if (processHandler == null || !allHandlers.contains(processHandler)) { + continue; + } + if (!processHandler.isProcessTerminated()) { + if (config.isRestartRequiresConfirmation()) { + DialogWrapper.DoNotAskOption option = new DialogWrapper.DoNotAskOption() { + @Override + public boolean isToBeShown() { + return config.isRestartRequiresConfirmation(); + } + + @Override + public void setToBeShown(boolean value, int exitCode) { + config.setRestartRequiresConfirmation(value); + } + + @Override + public boolean canBeHidden() { + return true; + } + + @Override + public boolean shouldSaveOptionsOnCancel() { + return false; + } + + @Override + public String getDoNotShowMessage() { + return CommonBundle.message("dialog.options.do.not.show"); + } + }; + if (Messages.OK != Messages.showOkCancelDialog(ExecutionBundle.message("rerun.confirmation.message", configuration.getName()), + ExecutionBundle.message("rerun.confirmation.title") + + " (" + + pair.getSecond().getId() + + ")", + CommonBundle.message("button.ok"), + CommonBundle.message("button.cancel"), + Messages.getQuestionIcon(), option)) { + return; + } + } + handlersToStop.add(processHandler); + stop(pair.getFirst()); + } + } + } + + if (handlersToStop.isEmpty()) { + ProgramRunnerUtil.executeConfiguration(project, configuration, executor, target); + return; + } + + Runnable runnable = new Runnable() { + @Override + public void run() { + for (ProcessHandler processHandler : handlersToStop) { + if (!processHandler.isProcessTerminated()) { + awaitingTerminationAlarm.addRequest(this, 100); + return; + } + } + ProgramRunnerUtil.executeConfiguration(project, configuration, executor, target); + } + }; + awaitingTerminationAlarm.addRequest(runnable, 100); + } + + private void forgetRunContentDescriptor(RunContentDescriptor runContentDescriptor) { + for ( + Iterator> iterator = myRunningConfigurations.iterator(); + iterator.hasNext(); ) { + Trinity trinity = iterator.next(); + if (trinity.getFirst() == runContentDescriptor) { + iterator.remove(); + return; + } + } + } + + private List> getRunningDescriptors(RunnerAndConfigurationSettings configuration) { + List> result = new ArrayList>(); + for (Trinity trinity : myRunningConfigurations) { + if (trinity.getSecond() == configuration) { + result.add(Pair.create(trinity.getFirst(), trinity.getThird())); + } + } + return result; + } + + + private void stop(@NotNull RunContentDescriptor runContentDescriptor) { + ProcessHandler processHandler = runContentDescriptor.getProcessHandler(); + if (processHandler == null) + return; + try { + if (processHandler instanceof KillableProcess && processHandler.isProcessTerminating()) { + ((KillableProcess)processHandler).killProcess(); + return; + } + + if (processHandler.detachIsDefault()) { + processHandler.detachProcess(); + } + else { + processHandler.destroyProcess(); + } + } + finally { + forgetRunContentDescriptor(runContentDescriptor); + } + } + + @NotNull + public String getComponentName() { + return "ExecutionManager"; + } + + private static class ProcessExecutionListener extends ProcessAdapter { + private final Project myProject; + private final RunProfile myProfile; + private final ProcessHandler myProcessHandler; + + public ProcessExecutionListener(Project project, RunProfile profile, ProcessHandler processHandler) { + myProject = project; + myProfile = profile; + myProcessHandler = processHandler; + } + + @Override + public void processTerminated(ProcessEvent event) { + if (myProject.isDisposed()) return; + + myProject.getMessageBus().syncPublisher(EXECUTION_TOPIC).processTerminated(myProfile, myProcessHandler); + } + + @Override + public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) { + if (myProject.isDisposed()) return; + + myProject.getMessageBus().syncPublisher(EXECUTION_TOPIC).processTerminating(myProfile, myProcessHandler); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java index 70e138e8416b..318823e4dc03 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java @@ -61,18 +61,20 @@ public class RestartAction extends AnAction implements DumbAware { } public void actionPerformed(final AnActionEvent e) { - ExecutionManager.getInstance(myEnvironment.getProject()).restartRunProfile(myEnvironment.getProject(), - myExecutor, - myEnvironment.getExecutionTarget(), - myEnvironment.getRunnerAndConfigurationSettings()); + Project project = myEnvironment.getProject(); + RunnerAndConfigurationSettings settings = myEnvironment.getRunnerAndConfigurationSettings(); + if (project == null || settings == null) + return; + ExecutionManager.getInstance(project).restartRunProfile(project, + myExecutor, + myEnvironment.getExecutionTarget(), + settings, + myProcessHandler); } + //Should be used by android framework only public void restart() { - doRestart(DataManager.getInstance().getDataContext(myDescriptor.getComponent())); - } - - private void doRestart(final DataContext dataContext) { - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myDescriptor.getComponent())); if (ExecutorRegistry.getInstance().isStarting(project, myExecutor.getId(), myRunner.getRunnerId())) { return; } @@ -96,16 +98,17 @@ public class RestartAction extends AnAction implements DumbAware { public void update(final AnActionEvent event) { final Presentation presentation = event.getPresentation(); String name = myEnvironment.getRunProfile().getName(); - if (name.startsWith(ActionsBundle.message("action.RerunFailedTests.text"))) - name = myEnvironment.getRunnerAndConfigurationSettings().getName(); - presentation.setText(ExecutionBundle.message("rerun.configuration.action.name", name)); - final boolean isRunning = myProcessHandler != null && !myProcessHandler.isProcessTerminated(); - if (myProcessHandler != null && !isRunning) { - myProcessHandler = null; // already terminated + if (name.startsWith(ActionsBundle.message("action.RerunFailedTests.text"))) { + RunnerAndConfigurationSettings settings = myEnvironment.getRunnerAndConfigurationSettings(); + if (settings != null) + name = settings.getName(); } - presentation.setIcon(isRunning ? STOP_AND_START_ICON : myIcon); + final boolean isRunning = myProcessHandler != null && !myProcessHandler.isProcessTerminated(); boolean isTerminating = myProcessHandler != null && myProcessHandler.isProcessTerminating(); boolean isStarting = ExecutorRegistry.getInstance().isStarting(myEnvironment.getProject(), myExecutor.getId(), myRunner.getRunnerId()); + + presentation.setText(ExecutionBundle.message("rerun.configuration.action.name", name)); + presentation.setIcon(isRunning ? STOP_AND_START_ICON : myIcon); presentation.setEnabled(!isStarting && !isTerminating); }