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