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