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