1 package com
.intellij
.xdebugger
.impl
;
3 import com
.intellij
.execution
.ExecutionManager
;
4 import com
.intellij
.execution
.executors
.DefaultDebugExecutor
;
5 import com
.intellij
.execution
.process
.ProcessHandler
;
6 import com
.intellij
.execution
.runners
.ExecutionEnvironment
;
7 import com
.intellij
.execution
.runners
.ProgramRunner
;
8 import com
.intellij
.execution
.ui
.RunContentDescriptor
;
9 import com
.intellij
.execution
.ui
.RunContentListener
;
10 import com
.intellij
.execution
.ui
.RunContentManager
;
11 import com
.intellij
.openapi
.components
.PersistentStateComponent
;
12 import com
.intellij
.openapi
.components
.ProjectComponent
;
13 import com
.intellij
.openapi
.components
.State
;
14 import com
.intellij
.openapi
.components
.Storage
;
15 import com
.intellij
.openapi
.diagnostic
.Logger
;
16 import com
.intellij
.openapi
.project
.Project
;
17 import com
.intellij
.openapi
.startup
.StartupManager
;
18 import com
.intellij
.openapi
.util
.Disposer
;
19 import com
.intellij
.openapi
.fileEditor
.FileEditorManagerListener
;
20 import com
.intellij
.openapi
.fileEditor
.FileEditorManagerAdapter
;
21 import com
.intellij
.openapi
.fileEditor
.FileEditorManager
;
22 import com
.intellij
.openapi
.vfs
.VirtualFile
;
23 import com
.intellij
.openapi
.vfs
.impl
.http
.HttpVirtualFile
;
24 import com
.intellij
.util
.containers
.HashMap
;
25 import com
.intellij
.util
.xmlb
.annotations
.Property
;
26 import com
.intellij
.util
.messages
.MessageBus
;
27 import com
.intellij
.xdebugger
.*;
28 import com
.intellij
.xdebugger
.impl
.breakpoints
.XBreakpointManagerImpl
;
29 import com
.intellij
.xdebugger
.impl
.ui
.ExecutionPointHighlighter
;
30 import com
.intellij
.xdebugger
.impl
.ui
.XDebugSessionData
;
31 import com
.intellij
.xdebugger
.impl
.ui
.XDebugSessionTab
;
32 import org
.jetbrains
.annotations
.NonNls
;
33 import org
.jetbrains
.annotations
.NotNull
;
34 import org
.jetbrains
.annotations
.Nullable
;
42 name
= XDebuggerManagerImpl
.COMPONENT_NAME
,
45 file
= "$WORKSPACE_FILE$")})
46 public class XDebuggerManagerImpl
extends XDebuggerManager
47 implements ProjectComponent
, PersistentStateComponent
<XDebuggerManagerImpl
.XDebuggerState
> {
48 private static final Logger LOG
= Logger
.getInstance("#com.intellij.xdebugger.impl.XDebuggerManagerImpl");
49 @NonNls public static final String COMPONENT_NAME
= "XDebuggerManager";
50 private final Project myProject
;
51 private final XBreakpointManagerImpl myBreakpointManager
;
52 private final Map
<ProcessHandler
, XDebugSessionData
> mySessionData
;
53 private final Map
<ProcessHandler
, XDebugSessionTab
> mySessionTabs
;
54 private final List
<XDebugSessionImpl
> mySessions
;
55 private final ExecutionPointHighlighter myExecutionPointHighlighter
;
56 private XDebugSessionImpl myLastActiveSession
;
58 private final RunContentListener myContentListener
= new RunContentListener() {
59 public void contentSelected(RunContentDescriptor descriptor
) {
62 public void contentRemoved(RunContentDescriptor descriptor
) {
63 XDebugSessionTab sessionTab
= mySessionTabs
.remove(descriptor
.getProcessHandler());
64 if (sessionTab
!= null) {
65 Disposer
.dispose(sessionTab
);
71 public XDebuggerManagerImpl(final Project project
, final StartupManager startupManager
, MessageBus messageBus
) {
73 myBreakpointManager
= new XBreakpointManagerImpl(project
, this, startupManager
);
74 mySessionData
= new LinkedHashMap
<ProcessHandler
, XDebugSessionData
>();
75 mySessions
= new ArrayList
<XDebugSessionImpl
>();
76 myExecutionPointHighlighter
= new ExecutionPointHighlighter(project
);
77 mySessionTabs
= new HashMap
<ProcessHandler
, XDebugSessionTab
>();
78 messageBus
.connect().subscribe(FileEditorManagerListener
.FILE_EDITOR_MANAGER
, new FileEditorManagerAdapter() {
80 public void fileOpened(final FileEditorManager source
, final VirtualFile file
) {
81 if (file
instanceof HttpVirtualFile
&& file
.equals(myExecutionPointHighlighter
.getCurrentFile())) {
82 myExecutionPointHighlighter
.update();
89 public XBreakpointManagerImpl
getBreakpointManager() {
90 return myBreakpointManager
;
93 public void projectOpened() {
94 RunContentManager contentManager
= ExecutionManager
.getInstance(myProject
).getContentManager();
95 LOG
.assertTrue(contentManager
!= null, "Content manager is null");
96 contentManager
.addRunContentListener(myContentListener
, DefaultDebugExecutor
.getDebugExecutorInstance());
99 public void projectClosed() {
100 final RunContentManager contentManager
= ExecutionManager
.getInstance(myProject
).getContentManager();
101 contentManager
.removeRunContentListener(myContentListener
);
104 public Project
getProject() {
110 public String
getComponentName() {
111 return COMPONENT_NAME
;
114 public void initComponent() {
117 public void disposeComponent() {
118 myBreakpointManager
.dispose();
122 public XDebugSession
startSession(@NotNull final ProgramRunner runner
,
123 @NotNull final ExecutionEnvironment env
,
124 @Nullable final RunContentDescriptor contentToReuse
,
125 @NotNull final XDebugProcessStarter processStarter
) {
126 return startSession(contentToReuse
, processStarter
, new XDebugSessionImpl(env
, runner
, this));
130 public XDebugSession
startSessionAndShowTab(@NotNull String sessionName
, @Nullable RunContentDescriptor contentToReuse
,
131 @NotNull XDebugProcessStarter starter
) {
132 XDebugSession session
= startSession(contentToReuse
, starter
, new XDebugSessionImpl(null, null, this, sessionName
));
133 RunContentDescriptor descriptor
= session
.getRunContentDescriptor();
134 ExecutionManager
.getInstance(myProject
).getContentManager().showRunContent(DefaultDebugExecutor
.getDebugExecutorInstance(), descriptor
);
135 ProcessHandler handler
= descriptor
.getProcessHandler();
136 if (handler
!= null) {
137 handler
.startNotify();
142 private XDebugSession
startSession(final RunContentDescriptor contentToReuse
, final XDebugProcessStarter processStarter
,
143 final XDebugSessionImpl session
) {
144 XDebugProcess process
= processStarter
.start(session
);
146 XDebugSessionData oldSessionData
= contentToReuse
!= null ? mySessionData
.remove(contentToReuse
.getProcessHandler()) : null;
147 if (oldSessionData
== null) {
148 oldSessionData
= new XDebugSessionData();
150 final XDebugSessionTab sessionTab
= session
.init(process
, oldSessionData
);
151 mySessions
.add(session
);
152 mySessionTabs
.put(session
.getDebugProcess().getProcessHandler(), sessionTab
);
157 public void removeSession(@NotNull XDebugSessionImpl session
) {
158 XDebugSessionTab sessionTab
= session
.getSessionTab();
159 XDebugSessionData data
= sessionTab
.saveData();
160 mySessions
.remove(session
);
161 mySessionData
.put(session
.getDebugProcess().getProcessHandler(), data
);
162 if (myLastActiveSession
== session
) {
163 myLastActiveSession
= null;
164 onActiveSessionChanged();
168 public void updateExecutionPosition(@NotNull XDebugSessionImpl session
, @Nullable XSourcePosition position
, boolean useSelection
) {
169 boolean sessionChanged
= myLastActiveSession
!= session
;
170 myLastActiveSession
= session
;
171 if (position
!= null) {
172 myExecutionPointHighlighter
.show(position
, useSelection
);
175 myExecutionPointHighlighter
.hide();
177 if (sessionChanged
) {
178 onActiveSessionChanged();
182 private void onActiveSessionChanged() {
183 myBreakpointManager
.getLineBreakpointManager().queueAllBreakpointsUpdate();
187 public XDebugSession
[] getDebugSessions() {
188 return mySessions
.toArray(new XDebugSession
[mySessions
.size()]);
193 public <T
extends XDebugProcess
> Collection
<?
extends T
> getDebugProcesses(Class
<T
> processClass
) {
194 final List
<T
> list
= new ArrayList
<T
>();
195 for (XDebugSessionImpl session
: mySessions
) {
196 final XDebugProcess process
= session
.getDebugProcess();
197 if (processClass
.isInstance(process
)) {
198 list
.add(processClass
.cast(process
));
205 public XDebugSessionImpl
getCurrentSession() {
206 if (myLastActiveSession
!= null) {
207 return myLastActiveSession
;
209 return !mySessions
.isEmpty() ? mySessions
.get(0) : null;
212 public XDebuggerState
getState() {
213 return new XDebuggerState(myBreakpointManager
.getState());
216 public void loadState(final XDebuggerState state
) {
217 myBreakpointManager
.loadState(state
.myBreakpointManagerState
);
220 public void showExecutionPosition() {
221 myExecutionPointHighlighter
.navigateTo();
224 public static class XDebuggerState
{
225 private XBreakpointManagerImpl
.BreakpointManagerState myBreakpointManagerState
;
227 public XDebuggerState() {
230 public XDebuggerState(final XBreakpointManagerImpl
.BreakpointManagerState breakpointManagerState
) {
231 myBreakpointManagerState
= breakpointManagerState
;
234 @Property(surroundWithTag
= false)
235 public XBreakpointManagerImpl
.BreakpointManagerState
getBreakpointManagerState() {
236 return myBreakpointManagerState
;
239 public void setBreakpointManagerState(final XBreakpointManagerImpl
.BreakpointManagerState breakpointManagerState
) {
240 myBreakpointManagerState
= breakpointManagerState
;