Optimized net.sourceforge.phpeclipse.xdebug.php.model.XDebugThread.getStackFrames()
[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         }
209         
210         /* (non-Javadoc)
211          * @see org.eclipse.debug.core.model.ISuspendResume#resume()
212          */
213         public void resume() throws DebugException {
214                 fBreakpoints=null;
215                 fTarget.resume();
216         }
217         
218         /* (non-Javadoc)
219          * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
220          */
221         public void suspend() throws DebugException {
222                 fTarget.suspend();
223         }
224         
225         /* (non-Javadoc)
226          * @see org.eclipse.debug.core.model.IStep#canStepInto()
227          */
228         public boolean canStepInto() {
229                 return isSuspended();
230         }
231         
232         /* (non-Javadoc)
233          * @see org.eclipse.debug.core.model.IStep#canStepOver()
234          */
235         public boolean canStepOver() {
236                 return isSuspended();
237         }
238         
239         /* (non-Javadoc)
240          * @see org.eclipse.debug.core.model.IStep#canStepReturn()
241          */
242         public boolean canStepReturn() {
243                 if (fStackFrames != null) {
244                         return (fStackFrames.length > 1);
245                 } else {
246                         return false;
247                 }
248         }
249
250         /* (non-Javadoc)
251          * @see org.eclipse.debug.core.model.IStep#isStepping()
252          */
253         public boolean isStepping() {
254                 return fStepping;
255         }
256
257         /* (non-Javadoc)
258          * @see org.eclipse.debug.core.model.IStep#stepInto()
259          */
260         public void stepInto() throws DebugException {
261                 fBreakpoints=null;
262                 fTarget.step_into();
263         }
264
265         /* (non-Javadoc)
266          * @see org.eclipse.debug.core.model.IStep#stepOver()
267          */
268         public void stepOver() throws DebugException {
269                 fBreakpoints=null;
270                 fTarget.step_over();
271         }
272
273         /* (non-Javadoc)
274          * @see org.eclipse.debug.core.model.IStep#stepReturn()
275          */
276         public void stepReturn() throws DebugException {
277                 fBreakpoints=null;
278                 fTarget.step_out();
279         }
280
281         /* (non-Javadoc)
282          * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
283          */
284         public boolean canTerminate() {
285                 return !isTerminated();
286         }
287
288         /* (non-Javadoc)
289          * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
290          */
291         public boolean isTerminated() {
292                 return fTerminated;
293         }
294
295         /* (non-Javadoc)
296          * @see org.eclipse.debug.core.model.ITerminate#terminate()
297          */
298         public void terminate() throws DebugException {
299                 fTarget.getDebugConnection().stop();
300                 fTerminated = true;
301         }
302         
303         public void terminated() throws DebugException {
304                 fTerminated = true;
305         }
306
307         /**
308          * Sets whether this thread is stepping
309          * 
310          * @param stepping whether stepping
311          */
312         protected void setStepping(boolean stepping) {
313                 fStepping = stepping;
314         }
315
316         public void handleDebugEvents(DebugEvent[] events) {
317                 DebugEvent de = events[0];
318                 System.out.println(de.toString());      
319         }
320
321         public void removeEventListeners() {
322                 DebugPlugin.getDefault().removeDebugEventListener(this);
323         }
324 }