Separate XDebugResponse from ResponseListner.
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / php / model / XDebugThread.java
1 /*
2  * Created on 23.11.2004
3  *
4  * TODO To change the template for this generated file go to
5  * Window - Preferences - Java - Code Style - Code Templates
6  */
7 package net.sourceforge.phpeclipse.xdebug.php.model;
8
9 import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils;
10 import net.sourceforge.phpeclipse.xdebug.core.xdebug.XDebugResponse;
11
12 import org.eclipse.debug.core.DebugEvent;
13 import org.eclipse.debug.core.DebugException;
14 import org.eclipse.debug.core.DebugPlugin;
15 import org.eclipse.debug.core.IDebugEventSetListener;
16 import org.eclipse.debug.core.model.IBreakpoint;
17 import org.eclipse.debug.core.model.IStackFrame;
18 import org.eclipse.debug.core.model.IThread;
19 import org.w3c.dom.Node;
20 import org.w3c.dom.NodeList;
21
22 /**
23  * @author Axel
24  *
25  * TODO To change the template for this generated type comment go to
26  * Window - Preferences - Java - Code Style - Code Templates
27  */
28 public class XDebugThread extends XDebugElement implements IThread, IDebugEventSetListener {
29         private XDebugStackFrame[]  fStackFrames;
30         
31         private IBreakpoint[] fBreakpoints;
32         
33         /* Whether this thread is stepping */
34         private boolean fStepping = false;
35         private boolean fTerminated = false;
36         
37         private int fStepCount = 0;
38         private int fCurrentStepCount = 0;
39         
40         /**
41          * Constructs a new thread for the given target
42          * 
43          * @param target VM
44          */
45         public XDebugThread(XDebugTarget target) {
46                 super(target);
47                 DebugPlugin.getDefault().addDebugEventListener(this);
48                 fStackFrames = null;
49         }
50         
51         public void incrementStepCounter() {
52                 fStepCount++;
53         }
54         public IStackFrame[] getStackFrames() throws DebugException {
55                 if (!isSuspended()) {
56                         return new IStackFrame[0];
57                 }
58                 
59                 if (fStepCount > fCurrentStepCount) {
60                         XDebugResponse dr = ((XDebugTarget) getDebugTarget()).getStackFrames();
61                         XDebugStackFrame[] newStackFrames = _getStackFrames(dr);
62
63                         /*if (fStackFrames != null) {
64                                 if (newStackFrames.length >= fStackFrames.length) {
65                                         int delta = newStackFrames.length - fStackFrames.length + 1;
66                                         
67                                         for (int i = fStackFrames.length - 1; i >= 0; i--) {
68                                                 if (fStackFrames[i].equals(newStackFrames[newStackFrames.length - delta])) {
69                                                         int b = 2; b++;
70                                                         //((XDebugStackFrame) newStackFrames[newStackFrames.length - delta]).evaluateChange((XDebugStackFrame) fStackFrames[i]);                                                                
71                                                 } else if (fStackFrames[i].isSameStackFrame(newStackFrames[newStackFrames.length - delta])) {
72                                                         int b = 2; b++;
73                                                         //((XDebugStackFrame) newStackFrames[newStackFrames.length - delta]).evaluateChange((XDebugStackFrame) fStackFrames[i]);                                                                
74                                                 }
75                                                 
76                                                 delta ++;
77                                         }
78                                 } else {
79                                         fStackFrames = newStackFrames;
80                                 }
81                         } else {
82                                 fStackFrames = newStackFrames;
83                         }*/
84
85                         fCurrentStepCount++;
86
87                         fStackFrames = newStackFrames;
88                 }
89
90                 return fStackFrames;
91         }
92         
93         
94         private XDebugStackFrame[] _getStackFrames(XDebugResponse lastResponse) {
95                 if (lastResponse.isError()) {
96                         return new XDebugStackFrame[0];
97                 }
98                 
99                 Node response = lastResponse.getParentNode();
100                 NodeList frames = response.getChildNodes();
101                 XDebugStackFrame[] theFrames = new XDebugStackFrame[frames.getLength()];
102                 
103                 for (int i = 0; i < frames.getLength(); i++) {
104                         Node stackNode = frames.item(i);
105                         String fileName=PHPDebugUtils.unescapeString(PHPDebugUtils.getAttributeValue(stackNode,"filename"));
106                         String lineNo = PHPDebugUtils.getAttributeValue(stackNode,"lineno");
107         
108                         XDebugStackFrame frame = new XDebugStackFrame(this/*fThread*/, i, /*type*/PHPDebugUtils.getAttributeValue(stackNode,"type"), /*lineno*/Integer.parseInt(lineNo), /*where*/PHPDebugUtils.getAttributeValue(stackNode,"where"), fileName);
109                         
110                         frame.incrementStepCounter();
111                         
112                         theFrames[i] = frame;
113                 }
114
115                 return theFrames;
116         }
117                         
118         /* (non-Javadoc)
119          * @see org.eclipse.debug.core.model.IThread#hasStackFrames()
120          */
121         public boolean hasStackFrames() throws DebugException {
122                 return isSuspended();
123         }
124         
125         /* (non-Javadoc)
126          * @see org.eclipse.debug.core.model.IThread#getPriority()
127          */
128         public int getPriority() throws DebugException {
129                 return 0;
130         }
131         
132         /* (non-Javadoc)
133          * @see org.eclipse.debug.core.model.IThread#getTopStackFrame()
134          */
135         public IStackFrame getTopStackFrame() throws DebugException {
136                 IStackFrame[] frames = getStackFrames();
137                 if (frames.length > 0) {
138                         return frames[0];
139                 }
140                 
141                 return null;
142         }
143         
144         /* (non-Javadoc)
145          * @see org.eclipse.debug.core.model.IThread#getName()
146          */
147         public String getName() throws DebugException {
148                 return "Thread[1]";
149         }
150
151         /* (non-Javadoc)
152          * @see org.eclipse.debug.core.model.IThread#getBreakpoints()
153          */
154         public IBreakpoint[] getBreakpoints() {
155                 if (fBreakpoints == null) {
156                         return new IBreakpoint[0];
157                 }
158                 return fBreakpoints;
159         }
160         
161         /**
162          * Sets the breakpoints this thread is suspended at, or <code>null</code>
163          * if none.
164          * 
165          * @param breakpoints the breakpoints this thread is suspended at, or <code>null</code>
166          * if none
167          */
168         protected void setBreakpoints(IBreakpoint[] breakpoints) {
169                 fBreakpoints = breakpoints;
170         }
171         
172         /* (non-Javadoc)
173          * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
174          */
175         public boolean canResume() {
176                 return isSuspended();
177         }
178         
179         /* (non-Javadoc)
180          * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
181          */
182         public boolean canSuspend() {
183                 return !isTerminated() && !isSuspended();
184         }
185         
186         /* (non-Javadoc)
187          * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
188          */
189         public boolean isSuspended() {
190                 return getDebugTarget().isSuspended();
191         }
192         
193         /* (non-Javadoc)
194          * @see org.eclipse.debug.core.model.ISuspendResume#resume()
195          */
196         public void resume() throws DebugException {
197                 fBreakpoints = null;
198                 getDebugTarget().resume();
199         }
200         
201         /* (non-Javadoc)
202          * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
203          */
204         public void suspend() throws DebugException {
205                 getDebugTarget().suspend();
206         }
207         
208         /* (non-Javadoc)
209          * @see org.eclipse.debug.core.model.IStep#canStepInto()
210          */
211         public boolean canStepInto() {
212                 return isSuspended();
213         }
214         
215         /* (non-Javadoc)
216          * @see org.eclipse.debug.core.model.IStep#canStepOver()
217          */
218         public boolean canStepOver() {
219                 return isSuspended();
220         }
221         
222         /* (non-Javadoc)
223          * @see org.eclipse.debug.core.model.IStep#canStepReturn()
224          */
225         public boolean canStepReturn() {
226                 if (fStackFrames != null) {
227                         return (fStackFrames.length > 1);
228                 } else {
229                         return false;
230                 }
231         }
232
233         /* (non-Javadoc)
234          * @see org.eclipse.debug.core.model.IStep#isStepping()
235          */
236         public boolean isStepping() {
237                 return fStepping;
238         }
239
240         /* (non-Javadoc)
241          * @see org.eclipse.debug.core.model.IStep#stepInto()
242          */
243         public void stepInto() throws DebugException {
244                 fBreakpoints = null;
245                 ((XDebugTarget) getDebugTarget()).step_into();
246         }
247
248         /* (non-Javadoc)
249          * @see org.eclipse.debug.core.model.IStep#stepOver()
250          */
251         public void stepOver() throws DebugException {
252                 fBreakpoints = null;
253                 ((XDebugTarget) getDebugTarget()).step_over();
254         }
255
256         /* (non-Javadoc)
257          * @see org.eclipse.debug.core.model.IStep#stepReturn()
258          */
259         public void stepReturn() throws DebugException {
260                 fBreakpoints = null;
261                 ((XDebugTarget) getDebugTarget()).step_out();
262         }
263
264         /* (non-Javadoc)
265          * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
266          */
267         public boolean canTerminate() {
268                 return !isTerminated();
269         }
270
271         /* (non-Javadoc)
272          * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
273          */
274         public boolean isTerminated() {
275                 return fTerminated;
276         }
277
278         /* (non-Javadoc)
279          * @see org.eclipse.debug.core.model.ITerminate#terminate()
280          */
281         public void terminate() throws DebugException {
282                 ((XDebugTarget) getDebugTarget()).getDebugConnection().stop();
283                 fTerminated = true;
284         }
285         
286         public void terminated() throws DebugException {
287                 fTerminated = true;
288         }
289
290         /**
291          * Sets whether this thread is stepping
292          * 
293          * @param stepping whether stepping
294          */
295         protected void setStepping(boolean stepping) {
296                 fStepping = stepping;
297         }
298
299         public void handleDebugEvents(DebugEvent[] events) {
300                 DebugEvent de = events[0];
301                 System.out.println(de.toString());      
302         }
303
304         public void removeEventListeners() {
305                 DebugPlugin.getDefault().removeDebugEventListener(this);
306         }
307         
308         /**
309          * Fires a <code>RESUME</code> event for this element with
310          * the given detail.
311          * 
312          * @param detail event detail code
313          */
314         public void fireResumeEvent(int detail) {
315                 fireEvent(new DebugEvent(this, DebugEvent.RESUME, detail));
316         }
317
318         /**
319          * Fires a <code>SUSPEND</code> event for this element with
320          * the given detail.
321          * 
322          * @param detail event detail code
323          */
324         public void fireSuspendEvent(int detail) {
325                 fireEvent(new DebugEvent(this, DebugEvent.SUSPEND, detail));
326         }
327 }