From 42c9e53017f8b4dfd2e283aa5afa927c15c42e42 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 28 Jul 2010 12:14:45 +0400 Subject: [PATCH] added topic about starting/stopping run configurations --- .../intellij/execution/ExecutionAdapter.java | 45 ++++++ .../intellij/execution/ExecutionListener.java | 38 +++++ .../intellij/execution/ExecutionManager.java | 9 +- .../intellij/execution/RunProfileStarter.java | 33 +++++ .../runners/GenericProgramRunner.java | 44 ++---- .../execution/impl/ExecutionManagerImpl.java | 140 +++++++++++++----- 6 files changed, 237 insertions(+), 72 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/execution/ExecutionAdapter.java create mode 100644 platform/lang-api/src/com/intellij/execution/ExecutionListener.java create mode 100644 platform/lang-api/src/com/intellij/execution/RunProfileStarter.java diff --git a/platform/lang-api/src/com/intellij/execution/ExecutionAdapter.java b/platform/lang-api/src/com/intellij/execution/ExecutionAdapter.java new file mode 100644 index 000000000000..85325b68aeb5 --- /dev/null +++ b/platform/lang-api/src/com/intellij/execution/ExecutionAdapter.java @@ -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) { + } +} diff --git a/platform/lang-api/src/com/intellij/execution/ExecutionListener.java b/platform/lang-api/src/com/intellij/execution/ExecutionListener.java new file mode 100644 index 000000000000..2e45ef7ac8d7 --- /dev/null +++ b/platform/lang-api/src/com/intellij/execution/ExecutionListener.java @@ -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); +} diff --git a/platform/lang-api/src/com/intellij/execution/ExecutionManager.java b/platform/lang-api/src/com/intellij/execution/ExecutionManager.java index 58e02af4f707..712d12c9f4a9 100644 --- a/platform/lang-api/src/com/intellij/execution/ExecutionManager.java +++ b/platform/lang-api/src/com/intellij/execution/ExecutionManager.java @@ -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 EXECUTION_TOPIC = new Topic("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); } diff --git a/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java b/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java new file mode 100644 index 000000000000..846b67b2f8a5 --- /dev/null +++ b/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java @@ -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; + +} diff --git a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java index cfde4926a0b9..8d8550e664cc 100644 --- a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java +++ b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java @@ -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 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; + } 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 9a37209fc431..9f18f4a66c7a 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java @@ -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, BeforeRunTask> activeProviders = new LinkedHashMap, BeforeRunTask>(); - for (final BeforeRunTaskProvider 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, BeforeRunTask> activeProviders = new LinkedHashMap, BeforeRunTask>(); + for (final BeforeRunTaskProvider 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 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 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); + } + } }