2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.execution
.runners
;
18 import com
.intellij
.diagnostic
.logging
.AdditionalTabComponent
;
19 import com
.intellij
.diagnostic
.logging
.LogConsoleImpl
;
20 import com
.intellij
.diagnostic
.logging
.LogConsoleManager
;
21 import com
.intellij
.diagnostic
.logging
.LogFilesManager
;
22 import com
.intellij
.execution
.DefaultExecutionResult
;
23 import com
.intellij
.execution
.ExecutionResult
;
24 import com
.intellij
.execution
.Executor
;
25 import com
.intellij
.execution
.configurations
.RunConfigurationBase
;
26 import com
.intellij
.execution
.configurations
.RunProfile
;
27 import com
.intellij
.execution
.process
.ProcessHandler
;
28 import com
.intellij
.execution
.ui
.*;
29 import com
.intellij
.execution
.ui
.actions
.CloseAction
;
30 import com
.intellij
.execution
.ui
.layout
.PlaceInGrid
;
31 import com
.intellij
.ide
.actions
.ContextHelpAction
;
32 import com
.intellij
.openapi
.Disposable
;
33 import com
.intellij
.openapi
.actionSystem
.*;
34 import com
.intellij
.openapi
.application
.ApplicationManager
;
35 import com
.intellij
.openapi
.project
.Project
;
36 import com
.intellij
.openapi
.ui
.ComponentWithActions
;
37 import com
.intellij
.openapi
.util
.Disposer
;
38 import com
.intellij
.openapi
.util
.IconLoader
;
39 import com
.intellij
.ui
.content
.Content
;
40 import com
.intellij
.ui
.content
.ContentManagerAdapter
;
41 import com
.intellij
.ui
.content
.ContentManagerEvent
;
42 import com
.intellij
.ui
.content
.tabs
.PinToolwindowTabAction
;
43 import org
.jetbrains
.annotations
.NonNls
;
44 import org
.jetbrains
.annotations
.NotNull
;
47 import javax
.swing
.event
.ChangeEvent
;
49 import java
.util
.ArrayList
;
50 import java
.util
.HashMap
;
56 public class RunContentBuilder
implements LogConsoleManager
, Disposable
{
57 private static final Icon DEFAULT_RERUN_ICON
= IconLoader
.getIcon("/actions/refreshUsages.png");
58 @NonNls private static final String JAVA_RUNNER
= "JavaRunner";
60 private final ProgramRunner myRunner
;
61 private final Project myProject
;
62 private final ArrayList
<Disposable
> myDisposeables
= new ArrayList
<Disposable
>();
63 private final ArrayList
<AnAction
> myRunnerActions
= new ArrayList
<AnAction
>();
64 private final Icon myRerunIcon
= DEFAULT_RERUN_ICON
;
65 private final boolean myReuseProhibited
= false;
66 private ExecutionResult myExecutionResult
;
68 private final LogFilesManager myManager
;
70 private RunnerLayoutUi myUi
;
71 private final Map
<AdditionalTabComponent
, Content
> myAdditionalContent
= new HashMap
<AdditionalTabComponent
, Content
>();
72 private final Executor myExecutor
;
73 private ExecutionEnvironment myEnvironment
;
75 public RunContentBuilder(final Project project
, final ProgramRunner runner
, Executor executor
) {
78 myExecutor
= executor
;
79 myManager
= new LogFilesManager(project
, this, this);
82 public ExecutionResult
getExecutionResult() {
83 return myExecutionResult
;
86 public void setExecutionResult(final ExecutionResult executionResult
) {
87 myExecutionResult
= executionResult
;
90 public void setEnvironment(@NotNull final ExecutionEnvironment env
) {
92 final RunProfile profile
= env
.getRunProfile();
93 if (profile
instanceof RunConfigurationBase
) {
94 myManager
.registerFileMatcher((RunConfigurationBase
)profile
);
98 public void addAction(@NotNull final AnAction action
) {
99 myRunnerActions
.add(action
);
102 public void dispose() {
103 for (Disposable disposable
: myDisposeables
) {
104 disposable
.dispose();
108 private RunContentDescriptor
createDescriptor() {
109 if (myExecutionResult
== null) {
110 throw new IllegalStateException("Missing ExecutionResult");
113 if (myEnvironment
== null) {
114 throw new IllegalStateException("Missing ExecutionEnvironment");
117 final RunProfile profile
= myEnvironment
.getRunProfile();
119 final ExecutionConsole console
= myExecutionResult
.getExecutionConsole();
120 final String runnerType
= console
instanceof ExecutionConsoleEx?
121 JAVA_RUNNER
+"." + ((ExecutionConsoleEx
)console
).getExecutionConsoleId(): JAVA_RUNNER
;
122 myUi
= RunnerLayoutUi
.Factory
.getInstance(myProject
).create(runnerType
, myExecutor
.getId(), profile
.getName(), this);
123 myUi
.getOptions().setMoveToGridActionEnabled(false).setMinimizeActionEnabled(false);
125 if (ApplicationManager
.getApplication().isUnitTestMode()) {
126 return new MyRunContentDescriptor(profile
, myExecutionResult
, myReuseProhibited
, myUi
.getComponent(), this);
129 if (console
!= null) {
130 if (console
instanceof ExecutionConsoleEx
) {
131 ((ExecutionConsoleEx
)console
).buildUi(myUi
);
134 buildConsoleUiDefault(console
);
136 if (profile
instanceof RunConfigurationBase
) {
137 myManager
.initLogConsoles((RunConfigurationBase
)profile
, myExecutionResult
.getProcessHandler());
140 MyRunContentDescriptor contentDescriptor
= new MyRunContentDescriptor(profile
, myExecutionResult
, myReuseProhibited
, myUi
.getComponent(), this);
141 myUi
.getOptions().setLeftToolbar(createActionToolbar(contentDescriptor
, myUi
.getComponent()), ActionPlaces
.UNKNOWN
);
143 return contentDescriptor
;
146 private void buildConsoleUiDefault(final ExecutionConsole console
) {
147 DefaultActionGroup consoleActions
= new DefaultActionGroup();
148 if (console
instanceof ConsoleView
) {
149 AnAction
[] actions
= ((ConsoleView
)console
).createConsoleActions();
150 for (AnAction goaction
: actions
) {
151 consoleActions
.add(goaction
);
155 final Content consoleContent
= myUi
.createContent("Console", console
.getComponent(), "Console",
156 IconLoader
.getIcon("/debugger/console.png"),
157 console
.getPreferredFocusableComponent());
159 consoleContent
.setActions(consoleActions
, ActionPlaces
.UNKNOWN
, console
.getComponent());
160 myUi
.addContent(consoleContent
, 0, PlaceInGrid
.bottom
, false);
163 public void addLogConsole(final String name
, final String path
, final long skippedContent
) {
164 final LogConsoleImpl log
= new LogConsoleImpl(myProject
, new File(path
), skippedContent
, name
, false){
165 public boolean isActive() {
166 final Content content
= myUi
.findContent(path
);
167 return content
!= null && content
.isSelected();
170 if (myEnvironment
.getRunProfile() instanceof RunConfigurationBase
) {
171 ((RunConfigurationBase
) myEnvironment
.getRunProfile()).customizeLogConsole(log
);
173 log
.attachStopLogConsoleTrackingListener(myExecutionResult
.getProcessHandler());
174 addAdditionalTabComponent(log
, path
);
176 Disposer
.register(this, log
);
178 myUi
.addListener(new ContentManagerAdapter() {
179 public void selectionChanged(final ContentManagerEvent event
) {
180 log
.stateChanged(new ChangeEvent(myUi
));
185 public void removeLogConsole(final String path
) {
186 final Content content
= myUi
.findContent(path
);
187 if (content
!= null) {
188 final LogConsoleImpl log
= (LogConsoleImpl
)content
.getComponent();
189 removeAdditionalTabComponent(log
);
193 private ActionGroup
createActionToolbar(final RunContentDescriptor contentDescriptor
, final JComponent component
) {
194 final DefaultActionGroup actionGroup
= new DefaultActionGroup();
196 final RestartAction restartAction
= new RestartAction(myExecutor
, myRunner
, getProcessHandler(), myRerunIcon
, contentDescriptor
, myEnvironment
);
197 restartAction
.registerShortcut(component
);
198 actionGroup
.add(restartAction
);
200 if (myExecutionResult
instanceof DefaultExecutionResult
) {
201 final AnAction
[] actions
= ((DefaultExecutionResult
)myExecutionResult
).getRestartActions();
202 if (actions
!= null) {
203 actionGroup
.addAll(actions
);
204 if (actions
.length
> 0) {
205 actionGroup
.addSeparator();
210 final AnAction stopAction
= ActionManager
.getInstance().getAction(IdeActions
.ACTION_STOP_PROGRAM
);
211 actionGroup
.add(stopAction
);
212 if (myExecutionResult
instanceof DefaultExecutionResult
) {
213 actionGroup
.addAll(((DefaultExecutionResult
)myExecutionResult
).getAdditionalStopActions());
216 actionGroup
.addAll(myExecutionResult
.getActions());
218 for (final AnAction anAction
: myRunnerActions
) {
219 if (anAction
!= null) {
220 actionGroup
.add(anAction
);
223 actionGroup
.addSeparator();
227 actionGroup
.addSeparator();
228 actionGroup
.add(myUi
.getOptions().getLayoutActions());
229 actionGroup
.addSeparator();
230 actionGroup
.add(PinToolwindowTabAction
.getPinAction());
231 actionGroup
.add(new CloseAction(myExecutor
, contentDescriptor
, myProject
));
232 actionGroup
.add(new ContextHelpAction(myExecutor
.getHelpId()));
236 public ProcessHandler
getProcessHandler() {
237 return myExecutionResult
.getProcessHandler();
241 * @param reuseContent see {@link RunContentDescriptor#myContent}
243 public RunContentDescriptor
showRunContent(final RunContentDescriptor reuseContent
) {
244 final RunContentDescriptor descriptor
= createDescriptor();
245 if(reuseContent
!= null) descriptor
.setAttachedContent(reuseContent
.getAttachedContent());
249 public void addAdditionalTabComponent(final AdditionalTabComponent tabComponent
, final String id
) {
250 final Content content
= myUi
.createContent(id
, (ComponentWithActions
)tabComponent
, tabComponent
.getTabTitle(),
251 IconLoader
.getIcon("/debugger/console.png"), tabComponent
.getPreferredFocusableComponent());
255 myUi
.addContent(content
);
256 myAdditionalContent
.put(tabComponent
, content
);
258 myDisposeables
.add(new Disposable(){
259 public void dispose() {
260 if (!myUi
.isDisposed()) {
261 removeAdditionalTabComponent(tabComponent
);
267 public void removeAdditionalTabComponent(AdditionalTabComponent component
) {
269 myDisposeables
.remove(component
);
270 final Content content
= myAdditionalContent
.remove(component
);
271 myUi
.removeContent(content
, true);
274 private static class MyRunContentDescriptor
extends RunContentDescriptor
{
275 private final boolean myReuseProhibited
;
276 private final Disposable myAdditionalDisposable
;
278 public MyRunContentDescriptor(final RunProfile profile
, final ExecutionResult executionResult
, final boolean reuseProhibited
, final JComponent component
, @NotNull Disposable additionalDisposable
) {
279 super(executionResult
.getExecutionConsole(), executionResult
.getProcessHandler(), component
, profile
.getName(), profile
.getIcon());
280 myReuseProhibited
= reuseProhibited
;
281 myAdditionalDisposable
= additionalDisposable
;
284 public boolean isContentReuseProhibited() {
285 return myReuseProhibited
;
288 public void dispose() {
289 Disposer
.dispose(myAdditionalDisposable
);