9b7b206966c9d42e968fca363a4137cdeaa91c97
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / php / model / XDebugTarget.java
1 /**
2  * 
3  */
4 package net.sourceforge.phpeclipse.xdebug.php.model;
5
6 import java.util.List;
7
8 import net.sourceforge.phpeclipse.xdebug.core.IPHPDebugEvent;
9 import net.sourceforge.phpeclipse.xdebug.core.IProxyEventListener;
10 import net.sourceforge.phpeclipse.xdebug.core.IXDebugPreferenceConstants;
11 import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils;
12 import net.sourceforge.phpeclipse.xdebug.core.PathMapItem;
13 import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
14 import net.sourceforge.phpeclipse.xdebug.core.XDebugProxy;
15 import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants;
16
17 import org.eclipse.core.resources.IMarker;
18 import org.eclipse.core.resources.IMarkerDelta;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.debug.core.DebugEvent;
22 import org.eclipse.debug.core.DebugException;
23 import org.eclipse.debug.core.DebugPlugin;
24 import org.eclipse.debug.core.IDebugEventSetListener;
25 import org.eclipse.debug.core.ILaunch;
26
27 import org.eclipse.debug.core.model.IBreakpoint;
28 import org.eclipse.debug.core.model.IDebugTarget;
29 import org.eclipse.debug.core.model.ILineBreakpoint;
30 import org.eclipse.debug.core.model.IMemoryBlock;
31 import org.eclipse.debug.core.model.IProcess;
32 import org.eclipse.debug.core.model.IThread;
33 import org.w3c.dom.NamedNodeMap;
34 import org.w3c.dom.Node;
35
36 import net.sourceforge.phpeclipse.xdebug.core.xdebug.ResponseListener;
37 import net.sourceforge.phpeclipse.xdebug.core.xdebug.XDebugConnection;
38 import net.sourceforge.phpeclipse.xdebug.core.xdebug.ResponseListener.XDebugResponse;
39
40 /**
41  * @author Christian
42  *
43  */
44 public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugEventSetListener, IProxyEventListener {
45         private IProcess fProcess;
46         
47         private ILaunch fLaunch;
48         
49         private int fDebugPort;
50         
51         private boolean fSuspended = false;
52         
53         private boolean fTerminated = false;
54         
55         private XDebugThread fThread;
56         private IThread[] fThreads;
57         
58         private XDebugConnection fDebugConnection;
59
60         private ResponseListener fResponseListener;
61
62         private String fIdeKey;
63
64
65         /**
66          * Constructs a new debug target in the given launch and waits until
67          * someone with the ideKey connects to the Debugproxy
68          *  
69          * 
70          * @param launch containing launch
71          * @param process process of the interpreter
72          * @param ideKey 
73          * @param pathMap Pathmap for the debug session
74          * @exception CoreException if unable to connect to host
75          */     
76         public XDebugTarget(ILaunch launch, IProcess process, String ideKey) throws CoreException {
77                 fLaunch = launch;
78                 fProcess = process;
79                 fDebugConnection = null;
80                 fThread = null;
81                 fThreads = new IThread[0];
82                 fIdeKey = ideKey;
83                 
84                 fDebugPort = XDebugCorePlugin.getDefault().getPreferenceStore().getInt(IXDebugPreferenceConstants.DEBUGPORT_PREFERENCE);                
85                 if (fDebugPort == 0) {
86                         fDebugPort = IXDebugPreferenceConstants.DEFAULT_DEBUGPORT;
87                 }
88                 
89                 DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this);
90                 DebugPlugin.getDefault().addDebugEventListener(this);
91         }
92
93         /* (non-Javadoc)
94          * @see org.eclipse.debug.core.model.IDebugTarget#getProcess()
95          */
96         public IProcess getProcess() {
97                 return fProcess;
98         }
99
100         /* (non-Javadoc)
101          * @see org.eclipse.debug.core.model.IDebugTarget#getThreads()
102          */
103         public IThread[] getThreads() throws DebugException {
104                 return fThreads;
105         }
106
107         /* (non-Javadoc)
108          * @see org.eclipse.debug.core.model.IDebugTarget#hasThreads()
109          */
110         public boolean hasThreads() throws DebugException {
111                 return (fThreads.length > 0);
112         }
113
114         /* (non-Javadoc)
115          * @see org.eclipse.debug.core.model.IDebugTarget#getName()
116          */
117         public String getName() throws DebugException {
118                 return "PHP XDebug Client at localhost:" + fDebugPort;
119         }
120
121         /* (non-Javadoc)
122          * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(org.eclipse.debug.core.model.IBreakpoint)
123          */
124         public boolean supportsBreakpoint(IBreakpoint breakpoint) {
125                 if (breakpoint.getModelIdentifier().equals(IXDebugConstants.ID_PHP_DEBUG_MODEL)) {
126                         return true;
127                 }
128                 return false;
129         }
130
131         /* (non-Javadoc)
132          * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
133          */
134         public IDebugTarget getDebugTarget() {
135                 return this;
136         }
137
138         /* (non-Javadoc)
139          * @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
140          */
141         public ILaunch getLaunch() {
142                 return fLaunch;
143         }
144
145         /* (non-Javadoc)
146          * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
147          */
148         public boolean canTerminate() {
149                 if (getProcess()!=null)  // ther is no running Process in remote debugging
150                         return getProcess().canTerminate();
151                 return true;
152         }
153
154         /* (non-Javadoc)
155          * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
156          */
157         public boolean isTerminated() {
158 //              return getProcess().isTerminated();
159                 return fTerminated;
160         }
161
162         /* (non-Javadoc)
163          * @see org.eclipse.debug.core.model.ITerminate#terminate()
164          */
165         public void terminate() throws DebugException {
166                 if(fTerminated) {
167                         return;
168                 }
169                 
170                 if (XDebugCorePlugin.getDefault() != null) {
171                         XDebugProxy proxy = XDebugCorePlugin.getDefault().getXDebugProxy();
172                         proxy.removeProxyEventListener(this, fIdeKey);
173                         
174                         System.out.println("XDebug.Target: ProxyEventlistener removed");
175                         
176                         fTerminated = true;
177                         fSuspended = false;
178                         
179                         XDebugCorePlugin.getBreakpointManager().removeBreakpointListener(this);
180                         fireTerminateEvent();
181                         DebugPlugin.getDefault().removeDebugEventListener(this);
182                         /*if (fThread!=null)
183                                 fThread.removeEventListeners();*/
184                 }
185         }
186
187         /* (non-Javadoc)
188          * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
189          */
190         public boolean canResume() {
191                 return false;
192         }
193
194         /* (non-Javadoc)
195          * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
196          */
197         public boolean canSuspend() {
198                 return false;
199         }
200
201         /* (non-Javadoc)
202          * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
203          */
204         public boolean isSuspended() {
205                 return fSuspended;
206         }
207
208         /* (non-Javadoc)
209          * @see org.eclipse.debug.core.model.ISuspendResume#resume()
210          */
211         public void resume() throws DebugException {
212                 if (fDebugConnection != null) {
213                         fThread.setBreakpoints(null);
214                         resumed(DebugEvent.RESUME);
215                         fDebugConnection.run();
216                 }               
217         }
218         
219         /**
220          * Notification the target has resumed for the given reason
221          * 
222          * @param detail reason for the resume
223          */
224         private void resumed(int detail) {
225                 fSuspended = false;
226                 fThread.fireResumeEvent(detail);
227         }
228         
229         /**
230          * Notification the target has suspended for the given reason
231          * 
232          * @param detail reason for the suspend
233          */
234         public void suspended(int detail) {
235                 fSuspended = true;
236                 fThread.fireSuspendEvent(detail);
237         }       
238         
239         /* (non-Javadoc)
240          * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
241          */
242         public void suspend() throws DebugException {
243         }
244
245         /* (non-Javadoc)
246          * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
247          */
248         public void breakpointAdded(IBreakpoint breakpoint) {
249                 IMarker marker = breakpoint.getMarker();
250                 IPath path = marker.getResource().getLocation();
251                 IPath cp = path.removeLastSegments(1);
252                 List pathMap = null;
253                 try {
254                         pathMap = fLaunch.getLaunchConfiguration().getAttribute(IXDebugConstants.ATTR_PHP_PATHMAP,(List)null);
255                 } catch (CoreException e2) {
256                         // TODO Auto-generated catch block
257                         e2.printStackTrace();
258                 }
259
260                 if (fDebugConnection != null)
261                 if (!fDebugConnection.isClosed()) {
262                         if (fProcess == null) {
263                                 PathMapItem pmi = null;
264                                 for (int i = 0; i < pathMap.size(); i++) {
265                                         pmi = new PathMapItem((String) pathMap.get(i));
266                                         IPath local = (IPath)pmi.getLocalPath().clone();
267                                         local = local.makeAbsolute();
268                                         int matchedSegments = local.segmentCount();
269                                         if (local.matchingFirstSegments(cp) == matchedSegments) {
270                                                 IPath newPath = pmi.getRemotePath();
271                                                 newPath = newPath.append(path.removeFirstSegments(matchedSegments));
272                                                 newPath = newPath.makeAbsolute();
273                                                 if (supportsBreakpoint(breakpoint)) {
274                                                         try {
275                                                                 if (breakpoint.isEnabled()) {
276                                                                         if (marker != null) {
277                                                                                 //XDebugResponse dr = fDebugConnection.breakpointSet(newPath.toString(), ((ILineBreakpoint)breakpoint).getLineNumber());
278
279                                                                                 int id = fDebugConnection.breakpointSet(newPath.toString(), ((ILineBreakpoint)breakpoint).getLineNumber(), marker.getAttribute(XDebugBreakpoint.HIT_COUNT,-1));
280                                                                                 XDebugResponse dr = getResponse(id);
281                                                                                 
282                                                                                 String bpid = dr.getAttributeValue("id");
283                                                                                 
284                                                                                 if (!"".equals(bpid))
285                                                                                         marker.setAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,Integer.parseInt(bpid));
286                                                                         }
287                                                                 }
288                                                         } catch (DebugException e) {
289                                                                 e.printStackTrace();
290                                                         } catch (CoreException e) {
291                                                                 e.printStackTrace();
292                                                         }
293                                                 }
294                                         }
295                                 }                       
296                         } else {
297                                 if (supportsBreakpoint(breakpoint)) {
298                                         try {
299                                                 if (breakpoint.isEnabled()) {
300                                                         if (marker != null) {
301                                                                 int id = fDebugConnection.breakpointSet(path.toString(), ((ILineBreakpoint)breakpoint).getLineNumber(), marker.getAttribute(XDebugBreakpoint.HIT_COUNT,-1));
302                                                                 XDebugResponse dr = getResponse(id);
303                                                                 String bpid = dr.getAttributeValue("id");
304                                                                 
305                                                                 if (!"".equals(bpid))
306                                                                         marker.setAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,Integer.parseInt(bpid));
307                                                         }
308                                                 }
309                                         } catch (DebugException e) {
310                                                 e.printStackTrace();
311                                         } catch (CoreException e) {
312                                                 e.printStackTrace();
313                                         }
314                                 }
315                         }
316                 }
317         }
318         
319         /* (non-Javadoc)
320          * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
321          */
322         public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
323                 if (supportsBreakpoint(breakpoint)) {
324                         try {
325                                 int id =((XDebugLineBreakpoint)breakpoint).getID();
326                                 if (id >0)
327                                         fDebugConnection.breakpointRemove(id);
328                         } catch (CoreException e) {
329                         }
330                 }
331         }
332
333         /* (non-Javadoc)
334          * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
335          */
336         public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
337 //              if (supportsBreakpoint(breakpoint)) {
338 //                      try {
339 //                              if (breakpoint.isEnabled()) {
340 //                                      breakpointAdded(breakpoint);
341 //                              } else {
342 //                                      breakpointRemoved(breakpoint, null);
343 //                              }
344 //                      } catch (CoreException e) {
345 //                      }
346 //              }
347         }
348
349         /* (non-Javadoc)
350          * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect()
351          */
352         public boolean canDisconnect() {
353                 return false;
354         }
355
356         /* (non-Javadoc)
357          * @see org.eclipse.debug.core.model.IDisconnect#disconnect()
358          */
359         public void disconnect() throws DebugException {
360         }
361
362         /* (non-Javadoc)
363          * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected()
364          */
365         public boolean isDisconnected() {
366                 return (false);
367 //              return (fDebugConnection==null);
368         }
369
370         /* (non-Javadoc)
371          * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval()
372          */
373         public boolean supportsStorageRetrieval() {
374                 return false;
375         }
376
377         /* (non-Javadoc)
378          * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long)
379          */
380         public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException {
381                 return null;
382         }
383
384         /**
385          * Notification we have connected to the PHP debugger and it has been started.
386          * Resume the the debugger.
387          */
388         public void started() throws DebugException {
389                 fThread.setBreakpoints(null);
390                 fThread.setStepping(false);
391
392                 int id = fDebugConnection.featureGet("detach");
393
394                 XDebugResponse response = getResponse(id);
395
396                 Integer.parseInt(response.getValue());
397                 System.out.println("in Target.started()");
398                 /*XDebugResponse response = fDebugConnection.featureGet("max_children");
399                 String a1 = response.getValue();
400                 System.out.println("max children:"+a1);
401                 XDebugResponse response1 = fDebugConnection.featureGet("max_children");
402                 String a2 = response1.getValue();
403                 System.out.println("max depth:"+a2);*/
404                 
405                 
406                 int id1 = fDebugConnection.featureSet("max_depth", "1024" );
407                 XDebugResponse response1 = getResponse(id1);
408                 if (response1.getAttributeValue("success").equals("1") ) {
409                         System.out.println("Set depth to 1024 (hack)");
410                 }
411                 int id2 = fDebugConnection.featureSet("max_children", "1024" );
412                 XDebugResponse response2 = getResponse(id2);
413                 if (response2.getAttributeValue("success").equals("1") ) {
414                         System.out.println("Set children to 1024 (hack)");
415                 }
416                 
417                 installDeferredBreakpoints();
418                 try {
419                         resume();
420                 } catch (DebugException e) {
421                         e.printStackTrace();
422                 }
423         }
424         
425         /**
426          * Install breakpoints that are already registered with the breakpoint
427          * manager.
428          */
429         private void installDeferredBreakpoints() {
430                 IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints();
431                 for (int i = 0; i < breakpoints.length; i++) {
432                         breakpointAdded(breakpoints[i]);
433                 }
434         }
435         
436         /**
437          * Returns the current stack frames in the target.
438          * 
439          * @return the current stack frames in the target
440          * @throws DebugException if unable to perform the request
441          */
442         public XDebugResponse getStackFrames() throws DebugException {
443                 int id = fDebugConnection.stackGet();
444                 XDebugResponse lastResponse = getResponse(id);
445                 return lastResponse;
446         }
447         
448         /**
449          * Single step the interpreter.
450          * 
451          * @throws DebugException if the request fails
452          */
453         protected void step_over() throws DebugException {
454                 fThread.setStepping(true);
455                 resumed(DebugEvent.STEP_OVER);
456                 fDebugConnection.stepOver();
457         }
458         
459         /**
460          * Single step the interpreter.
461          * 
462          * @throws DebugException if the request fails
463          */
464         protected void step_into() throws DebugException {
465                 fThread.setStepping(true);
466                 resumed(DebugEvent.STEP_INTO);
467                 fDebugConnection.stepInto();
468         }
469         
470         /**
471          * Single step the interpreter.
472          * 
473          * @throws DebugException if the request fails
474          */
475         protected void step_out() throws DebugException {
476                 fThread.setStepping(true);
477                 resumed(DebugEvent.STEP_RETURN);
478                 fDebugConnection.stepOut();
479         }
480         
481         public boolean setVarValue(String name, String value) {
482                 int id = fDebugConnection.setVarValue(name,value);
483                 XDebugResponse response = getResponse(id);
484                 
485                 if ((response.getAttributeValue("success")).equals("1")) {
486                         return true;
487                 } else {
488                         return false;
489                 }
490         }
491         
492         public Node eval(String expression) {
493                 int id = fDebugConnection.eval(expression);
494                 XDebugResponse response = getResponse(id);
495
496                 Node evalResponse = response.getParentNode();
497                 Node evalProperty = evalResponse.getFirstChild();
498                 
499                 return evalProperty;
500         }
501         
502         public void handleDebugEvents(DebugEvent[] events) {
503                 for (int i = 0; i < events.length; i++) {
504                         DebugEvent event = events[i];
505                         
506                         if (fResponseListener != null) {
507                                 Object s = null;
508                                 s = event.getSource();
509                                 if (s instanceof ResponseListener) {
510                                         if (!fResponseListener.equals((ResponseListener) s)) {
511                                                 return;
512                                         }
513                                 }
514                         } else {
515                                 return;
516                         }
517                         
518                         if (event.getKind() == DebugEvent.MODEL_SPECIFIC) {
519                                 switch (event.getDetail()) {
520                                         case IPHPDebugEvent.BREAKPOINT_HIT:
521                                                 int id = fDebugConnection.stackGet();
522                                                 XDebugResponse lastResponse = getResponse(id);
523
524                                                 IBreakpoint breakpoint = breakpointHit(lastResponse.getParentNode());
525                                                 
526                                                 if (breakpoint != null) {
527                                                         fThread.setBreakpoints(new IBreakpoint[]{breakpoint});
528                                                         fThread.incrementStepCounter();
529                                                         suspended(DebugEvent.BREAKPOINT);
530                                                 } else {
531                                                         try {
532                                                                 resume();
533                                                         } catch (DebugException e ) {
534                                                                 ; //nothing to do
535                                                         }
536                                                 }
537                                                 break;
538                                         case IPHPDebugEvent.STEP_END:
539                                                 fThread.incrementStepCounter();
540                                                 suspended(DebugEvent.STEP_END);
541                                                 break;
542                                         case IPHPDebugEvent.STOPPED:
543                                                 stopped();
544                                                 break;
545                                 }
546                         }
547                 }
548         }
549         
550         public void stopped() {
551                 if(fDebugConnection == null) {
552                         return;
553                 }
554
555                 resumed(DebugEvent.TERMINATE);
556
557                 stopListener();
558                 fDebugConnection.close();
559
560                 fThread.removeEventListeners();
561                 fThread = null;
562                 fThreads = new IThread[0];
563                 
564 /*              stopListener();
565                 fDebugConnection.close();*/
566
567                 fSuspended = false;
568
569                 // Dirty hack to check debugging mode (remote or local)
570                 if (fProcess!=null) {
571                         try {
572                                 terminate();
573                         } catch (DebugException e) {
574                                 e.printStackTrace();
575                         }
576                 } else {
577                         fDebugConnection = null;
578                         fireEvent(new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CONTENT));
579                 }               
580         }
581         
582         public void handleProxyEvent(/*String ideKey,*/ XDebugConnection connection) {
583                 setDebugConnection(connection);
584                 System.out.println("* New Connection - XDebug.Target: " + fDebugConnection.getSessionID());
585                 
586                 fireEvent(new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CHANGE));
587                 
588                 fThread = new XDebugThread(this);
589                 fThreads = new IThread[] {fThread};
590                 try {
591                         started();
592                 } catch( DebugException e ){
593                         e.printStackTrace();            
594                 }               
595         }
596
597         private void setDebugConnection(XDebugConnection connection) {
598                 if (connection != null) {
599                         fDebugConnection = connection;
600                         fResponseListener = new ResponseListener(connection);
601                         startListener();
602                 }
603         }
604         
605         /**
606          * @return Returns the fDebugConnection.
607          */
608         public XDebugConnection getDebugConnection() {
609                 return fDebugConnection;
610         }       
611         
612         public void addProcess(IProcess p) {
613                 fProcess = p;
614
615         }
616         public Node getLocalVariables(int level) throws DebugException {
617 //              XDebugResponse response = fDebugConnection.contextGet(level, 0);
618                 int id = fDebugConnection.contextGet(level, 0);
619                 XDebugResponse response = getResponse(id);
620                 
621                 return response.getParentNode();
622         }
623         
624         public Node getGlobalVariables(int level) throws DebugException {
625                 //XDebugResponse response = fDebugConnection.contextGet(level, 1);
626
627                 int id = fDebugConnection.contextGet(level, 1);
628                 XDebugResponse response = getResponse(id);
629                 
630                 return response.getParentNode();
631         }
632         
633         public void stop() {
634                 fDebugConnection.stop();
635         }
636         
637         protected IBreakpoint breakpointHit(Node node) {
638                 Node child = node.getFirstChild();
639                 if (child.getNodeName().equals("stack")) {
640                         int lineNumber = Integer.parseInt(PHPDebugUtils.getAttributeValue(child, "lineno"));
641                         String filename = PHPDebugUtils.getAttributeValue(child, "filename");  
642                         IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints();
643                         for (int i = 0; i < breakpoints.length; i++) {
644                                 IBreakpoint breakpoint = breakpoints[i];
645                                 if (supportsBreakpoint(breakpoint)) {
646                                         if (breakpoint instanceof ILineBreakpoint) {
647                                                 ILineBreakpoint lineBreakpoint = (ILineBreakpoint) breakpoint;
648                                                 try {                                           
649                                                         if (breakpoint.isEnabled()) {
650                                                                 IMarker marker = breakpoint.getMarker();
651                                                                 if (marker != null) {
652                                                                         String endfilename;
653                                                                         
654                                                                         if (getProcess() == null) {
655                                                                                 endfilename = marker.getResource().getLocation().lastSegment(); 
656                                                                         } else {
657                                                                                 endfilename = marker.getResource().getLocation().toOSString();
658                                                                         }
659                                                                         
660                                                                         int id = fDebugConnection.breakpointGet(marker.getAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,-1));
661                                                                         XDebugResponse dr = getResponse(id);
662                                                                         
663                                                                         //String bpid = dr.getAttributeValue("command");                                                                        
664                                                                         Node hitCo = dr.getParentNode().getFirstChild();
665                                                                         int hitCount = 0;
666                                                                         if (hitCo.hasAttributes()) {
667                                                                                 NamedNodeMap listAttribute = hitCo.getAttributes();
668                                                                                 Node attribute = listAttribute.getNamedItem("hit_count");
669                                                                                 if (attribute !=null) {
670                                                                                         hitCount = Integer.parseInt(attribute.getNodeValue());
671                                                                                 }
672                                                                         }
673
674                                                                         //String hitCount = hitCo.getAttributeValue("hit_count");                                                                       
675                                                                         if(PHPDebugUtils.unescapeString(filename).endsWith(endfilename)
676                                                                                         && (lineBreakpoint.getLineNumber() == lineNumber) ) {
677                                                                                 if (marker.getAttribute(XDebugLineBreakpoint.HIT_COUNT, 0) > 0) {
678                                                                                         if (marker.getAttribute(XDebugLineBreakpoint.HIT_COUNT, 0) == hitCount) {
679                                                                                                 return (breakpoint);                                                                                            
680                                                                                         }
681                                                                                 } else {
682                                                                                         return (breakpoint);
683                                                                                 }
684                                                                         }
685                                                                 }
686                                                         }
687                                                 } catch (CoreException e) {
688                                                 }
689                                         }
690                                 }
691                         }
692                 }
693                 
694                 return null;
695         }
696         
697         public void startListener() {
698                 fResponseListener.schedule();
699         }
700         
701         public /*boolean*/ void stopListener() {
702                 /*return*/ fResponseListener.cancel(); //done(null); //.cancel();
703         }
704         public XDebugResponse getResponse(int id) {
705                 XDebugResponse response = fResponseListener.getResponse(id);
706
707                 return response;
708         }
709 }