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