Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Jemerov
2012-07-17 21:37:22 +02:00
7 changed files with 819 additions and 765 deletions
@@ -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<ExecutionListener> EXECUTION_TOPIC
= new Topic<ExecutionListener>("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<ExecutionListener> EXECUTION_TOPIC
= new Topic<ExecutionListener>("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);
}
@@ -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<Executor> myExecutors = new ArrayList<Executor>();
private ActionManager myActionManager;
private final Map<String, Executor> myId2Executor = new HashMap<String, Executor>();
private final Set<String> myContextActionIdSet = new HashSet<String>();
private final Map<String, AnAction> myId2Action = new HashMap<String, AnAction>();
private final Map<String, AnAction> myContextActionId2Action = new HashMap<String, AnAction>();
// [Project, ExecutorId, RunnerId]
private final Set<Trinity<Project, String, String>> myInProgress = Collections.synchronizedSet(new java.util.HashSet<Trinity<Project, String, String>>());
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<String, AnAction> 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<String, AnAction> 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<Trinity<Project, String, String>> it = myInProgress.iterator(); it.hasNext(); ) {
final Trinity<Project, String, String> 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<Project, String, String> createExecutionId(String executorId, ExecutionEnvironment env, Project project) {
final ConfigurationPerRunnerSettings settings = env.getConfigurationSettings();
return new Trinity<Project, String, String>(project, executorId, settings != null? settings.getRunnerId() : null);
}
public boolean isStarting(Project project, final String executorId, final String runnerId) {
return myInProgress.contains(new Trinity<Project, String, String>(project, executorId, runnerId));
}
public synchronized void disposeComponent() {
if (myExecutors.size() > 0) {
List<Executor> executors = new ArrayList<Executor>(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<Executor> myExecutors = new ArrayList<Executor>();
private ActionManager myActionManager;
private final Map<String, Executor> myId2Executor = new HashMap<String, Executor>();
private final Set<String> myContextActionIdSet = new HashSet<String>();
private final Map<String, AnAction> myId2Action = new HashMap<String, AnAction>();
private final Map<String, AnAction> myContextActionId2Action = new HashMap<String, AnAction>();
// [Project, ExecutorId, RunnerId]
private final Set<Trinity<Project, String, String>> myInProgress = Collections.synchronizedSet(new java.util.HashSet<Trinity<Project, String, String>>());
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<String, AnAction> 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<String, AnAction> 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<Trinity<Project, String, String>> it = myInProgress.iterator(); it.hasNext(); ) {
final Trinity<Project, String, String> 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<Project, String, String> createExecutionId(String executorId, ExecutionEnvironment env, Project project) {
final ConfigurationPerRunnerSettings settings = env.getConfigurationSettings();
return new Trinity<Project, String, String>(project, executorId, settings != null? settings.getRunnerId() : null);
}
public boolean isStarting(Project project, final String executorId, final String runnerId) {
return myInProgress.contains(new Trinity<Project, String, String>(project, executorId, runnerId));
}
public synchronized void disposeComponent() {
if (myExecutors.size() > 0) {
List<Executor> executors = new ArrayList<Executor>(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);
}
}
}
@@ -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<Boolean, Boolean> b = isEnabledAndVisible(context);
presentation.setEnabled(b.first);
presentation.setVisible(b.second);
}
private Pair<Boolean, Boolean> 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<Boolean, Boolean> b = isEnabledAndVisible(context);
presentation.setEnabled(b.first);
presentation.setVisible(b.second);
}
private Pair<Boolean, Boolean> 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);
}
}
@@ -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<Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor>> myRunningConfigurations =
new ArrayList<Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor>>();
/**
* 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<ProcessHandler> handlers = new ArrayList<ProcessHandler>();
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<BeforeRunTask> activeTasks = new ArrayList<BeforeRunTask>();
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<BeforeRunTask> 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<Pair<RunContentDescriptor, Executor>> pairs = getRunningDescriptors(configuration);
for (Pair<RunContentDescriptor, Executor> 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<Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor>> iterator = myRunningConfigurations.iterator();
iterator.hasNext(); ) {
Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor> 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<RunContentDescriptor, Executor> 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<Pair<RunContentDescriptor, Executor>> getRunningDescriptors(RunnerAndConfigurationSettings configuration) {
List<Pair<RunContentDescriptor, Executor>> result = new ArrayList<Pair<RunContentDescriptor, Executor>>();
for (Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor> 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<Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor>> myRunningConfigurations =
new ArrayList<Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor>>();
/**
* 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<ProcessHandler> handlers = new ArrayList<ProcessHandler>();
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<BeforeRunTask> activeTasks = new ArrayList<BeforeRunTask>();
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<BeforeRunTask> 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<ProcessHandler> allHandlers = new ArrayList<ProcessHandler>();
final List<ProcessHandler> handlersToStop = new ArrayList<ProcessHandler>();
final List<Pair<RunContentDescriptor, Executor>> pairs = getRunningDescriptors(configuration);
if (configuration.isSingleton()) {
for (Pair<RunContentDescriptor, Executor> pair : pairs) {
allHandlers.add(pair.getFirst().getProcessHandler());
}
}
else if (handler != null) {
allHandlers.add(handler);
}
if (!allHandlers.isEmpty()) {
for (Pair<RunContentDescriptor, Executor> 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<Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor>> iterator = myRunningConfigurations.iterator();
iterator.hasNext(); ) {
Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor> trinity = iterator.next();
if (trinity.getFirst() == runContentDescriptor) {
iterator.remove();
return;
}
}
}
private List<Pair<RunContentDescriptor, Executor>> getRunningDescriptors(RunnerAndConfigurationSettings configuration) {
List<Pair<RunContentDescriptor, Executor>> result = new ArrayList<Pair<RunContentDescriptor, Executor>>();
for (Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor> 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);
}
}
}
@@ -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);
}
@@ -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() {
@@ -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() {