added topic about starting/stopping run configurations

This commit is contained in:
nik
2010-07-28 12:18:29 +04:00
parent 9864bf5680
commit 42c9e53017
6 changed files with 237 additions and 72 deletions
@@ -0,0 +1,45 @@
/*
* Copyright 2000-2010 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.RunProfile;
import com.intellij.execution.process.ProcessHandler;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class ExecutionAdapter implements ExecutionListener {
@Override
public void processStarting(@NotNull RunProfile runProfile) {
}
@Override
public void processNotStarted(@NotNull RunProfile runProfile) {
}
@Override
public void processStarted(@NotNull RunProfile runProfile, @NotNull ProcessHandler handler) {
}
@Override
public void processTerminating(@NotNull RunProfile runProfile, @NotNull ProcessHandler handler) {
}
@Override
public void processTerminated(@NotNull RunProfile runProfile, @NotNull ProcessHandler handler) {
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2000-2010 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.RunProfile;
import com.intellij.execution.process.ProcessHandler;
import org.jetbrains.annotations.NotNull;
import java.util.EventListener;
/**
* @author nik
*/
public interface ExecutionListener extends EventListener {
void processStarting(@NotNull RunProfile runProfile);
void processNotStarted(@NotNull RunProfile runProfile);
void processStarted(@NotNull RunProfile runProfile, @NotNull ProcessHandler handler);
void processTerminating(@NotNull RunProfile runProfile, @NotNull ProcessHandler handler);
void processTerminated(@NotNull RunProfile runProfile, @NotNull ProcessHandler handler);
}
@@ -18,10 +18,16 @@ package com.intellij.execution;
import com.intellij.execution.configurations.RunProfile;
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;
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);
}
@@ -32,5 +38,6 @@ public abstract class ExecutionManager {
public abstract ProcessHandler[] getRunningProcesses();
public abstract void startRunProfile(@NotNull RunProfileStarter starter, @NotNull RunProfileState state,
@NotNull Project project, @NotNull Executor executor, @NotNull ExecutionEnvironment env);
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2010 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.runners.ExecutionEnvironment;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
public abstract class RunProfileStarter {
@Nullable
public abstract RunContentDescriptor execute(@NotNull Project project, @NotNull Executor executor, @NotNull RunProfileState state,
@Nullable RunContentDescriptor contentToReuse, @NotNull ExecutionEnvironment env) throws ExecutionException;
}
@@ -18,12 +18,9 @@ package com.intellij.execution.runners;
import com.intellij.execution.*;
import com.intellij.execution.configurations.*;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.history.LocalHistory;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.JDOMExternalizable;
@@ -67,51 +64,34 @@ public abstract class GenericProgramRunner<Settings extends JDOMExternalizable>
public void execute(@NotNull final Executor executor, @NotNull final ExecutionEnvironment env, @Nullable final Callback callback)
throws ExecutionException {
final RunProfile profile = env.getRunProfile();
final Project project = env.getProject();
if (project == null) {
return;
}
final RunContentDescriptor reuseContent =
ExecutionManager.getInstance(project).getContentManager().getReuseContent(executor, env.getContentToReuse());
final RunProfileState state = env.getState(executor);
if (state == null) {
return;
}
Runnable startRunnable = new Runnable() {
public void run() {
try {
if (project.isDisposed()) return;
final RunContentDescriptor descriptor =
doExecute(project, executor, state, reuseContent, env);
if (callback != null) callback.processStarted(descriptor);
if (descriptor != null) {
ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor);
final ProcessHandler processHandler = descriptor.getProcessHandler();
if (processHandler != null) processHandler.startNotify();
}
}
catch (ExecutionException e) {
ExecutionUtil.handleExecutionError(project, executor.getToolWindowId(), profile, e);
}
ExecutionManager.getInstance(project).startRunProfile(new RunProfileStarter() {
@Override
public RunContentDescriptor execute(@NotNull Project project,
@NotNull Executor executor,
@NotNull RunProfileState state,
@Nullable RunContentDescriptor contentToReuse,
@NotNull ExecutionEnvironment env) throws ExecutionException {
final RunContentDescriptor descriptor = doExecute(project, executor, state, contentToReuse, env);
if (callback != null) callback.processStarted(descriptor);
return descriptor;
}
};
if (ApplicationManager.getApplication().isUnitTestMode()) {
startRunnable.run();
}
else {
ExecutionManager.getInstance(project).compileAndRun(startRunnable, profile, state);
}
}, state, project, executor, env);
}
@Nullable
protected abstract RunContentDescriptor doExecute(final Project project, final Executor executor, final RunProfileState state,
final RunContentDescriptor contentToReuse,
final ExecutionEnvironment env) throws ExecutionException;
}
@@ -16,14 +16,16 @@
package com.intellij.execution.impl;
import com.intellij.execution.BeforeRunTask;
import com.intellij.execution.BeforeRunTaskProvider;
import com.intellij.execution.ExecutionManager;
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;
@@ -64,7 +66,8 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
public void projectClosed() {
}
public void initComponent() { }
public void initComponent() {
}
public void disposeComponent() {
}
@@ -94,53 +97,112 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
public void compileAndRun(final Runnable startRunnable,
final RunProfile configuration,
final RunProfileState state) {
final Runnable antAwareRunnable = new Runnable() {
public void run() {
if (configuration instanceof RunConfiguration) {
final RunConfiguration runConfiguration = (RunConfiguration)configuration;
final RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(myProject);
if (configuration instanceof RunConfiguration) {
final RunConfiguration runConfiguration = (RunConfiguration)configuration;
final RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(myProject);
final Map<BeforeRunTaskProvider<BeforeRunTask>, BeforeRunTask> activeProviders = new LinkedHashMap<BeforeRunTaskProvider<BeforeRunTask>, BeforeRunTask>();
for (final BeforeRunTaskProvider<BeforeRunTask> provider : Extensions.getExtensions(BeforeRunTaskProvider.EXTENSION_POINT_NAME, myProject)) {
final BeforeRunTask task = runManager.getBeforeRunTask(runConfiguration, provider.getId());
if (task != null && task.isEnabled()) {
activeProviders.put(provider, task);
final Map<BeforeRunTaskProvider<BeforeRunTask>, BeforeRunTask> activeProviders = new LinkedHashMap<BeforeRunTaskProvider<BeforeRunTask>, BeforeRunTask>();
for (final BeforeRunTaskProvider<BeforeRunTask> provider : Extensions.getExtensions(BeforeRunTaskProvider.EXTENSION_POINT_NAME, myProject)) {
final BeforeRunTask task = runManager.getBeforeRunTask(runConfiguration, provider.getId());
if (task != null && task.isEnabled()) {
activeProviders.put(provider, task);
}
}
if (!activeProviders.isEmpty()) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
ConfigurationPerRunnerSettings configurationSettings = state.getConfigurationSettings();
DataContext projectContext = SimpleDataContext.getProjectContext(myProject);
final DataContext dataContext = configurationSettings != null ? SimpleDataContext
.getSimpleContext(BeforeRunTaskProvider.RUNNER_ID, configurationSettings.getRunnerId(), projectContext) : projectContext;
for (BeforeRunTaskProvider<BeforeRunTask> provider : activeProviders.keySet()) {
if(!provider.executeTask(dataContext, runConfiguration, activeProviders.get(provider))) {
return;
}
}
DumbService.getInstance(myProject).smartInvokeLater(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();
Runnable startRunnable = new Runnable() {
public void run() {
boolean started = false;
try {
if (project.isDisposed()) return;
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarting(profile);
final RunContentDescriptor descriptor = starter.execute(project, executor, state, reuseContent, env);
if (descriptor != null) {
ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor);
final ProcessHandler processHandler = descriptor.getProcessHandler();
if (processHandler != null) {
processHandler.startNotify();
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarted(profile, processHandler);
started = true;
processHandler.addProcessListener(new ProcessExecutionListener(project, profile, processHandler));
}
}
if (!activeProviders.isEmpty()) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
ConfigurationPerRunnerSettings configurationSettings = state.getConfigurationSettings();
DataContext projectContext = SimpleDataContext.getProjectContext(myProject);
final DataContext dataContext = configurationSettings != null ? SimpleDataContext
.getSimpleContext(BeforeRunTaskProvider.RUNNER_ID, configurationSettings.getRunnerId(), projectContext) : projectContext;
for (BeforeRunTaskProvider<BeforeRunTask> provider : activeProviders.keySet()) {
if(!provider.executeTask(dataContext, runConfiguration, activeProviders.get(provider))) {
return;
}
}
DumbService.getInstance(myProject).smartInvokeLater(startRunnable);
}
});
}
else {
startRunnable.run();
}
}
else {
startRunnable.run();
catch (ExecutionException e) {
ExecutionUtil.handleExecutionError(project, executor.getToolWindowId(), profile, e);
}
if (!started) {
project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(profile);
}
}
};
antAwareRunnable.run();
//ApplicationManager.getApplication().invokeLater(antAwareRunnable);
if (ApplicationManager.getApplication().isUnitTestMode()) {
startRunnable.run();
}
else {
compileAndRun(startRunnable, profile, state);
}
}
@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) {
myProject.getMessageBus().syncPublisher(EXECUTION_TOPIC).processTerminated(myProfile, myProcessHandler);
}
@Override
public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) {
myProject.getMessageBus().syncPublisher(EXECUTION_TOPIC).processTerminating(myProfile, myProcessHandler);
}
}
}