X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugTarget.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugTarget.java index b8d3f86..11bb134 100644 --- a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugTarget.java +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugTarget.java @@ -1,142 +1,209 @@ /** - * + * */ package net.sourceforge.phpeclipse.xdebug.php.model; -import net.sourceforge.phpeclipse.xdebug.core.Base64; -import net.sourceforge.phpeclipse.xdebug.core.DebugConnection; +//import java.io.ByteArrayInputStream; +//import java.io.IOException; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.xdebug.core.IPHPDebugEvent; +import net.sourceforge.phpeclipse.xdebug.core.IProxyEventListener; +import net.sourceforge.phpeclipse.xdebug.core.IXDebugPreferenceConstants; import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils; +import net.sourceforge.phpeclipse.xdebug.core.PathMapItem; import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; -import net.sourceforge.phpeclipse.xdebug.core.DebugConnection.DebugResponse; +import net.sourceforge.phpeclipse.xdebug.core.XDebugProxy; import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IDebugEventSetListener; import org.eclipse.debug.core.ILaunch; + import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.ILineBreakpoint; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IProcess; -import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; -import org.eclipse.debug.core.model.IValue; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; -import org.w3c.dom.NodeList; +//import org.xml.sax.SAXException; + +import net.sourceforge.phpeclipse.xdebug.core.xdebug.ResponseListener; +import net.sourceforge.phpeclipse.xdebug.core.xdebug.XDebugConnection; +import net.sourceforge.phpeclipse.xdebug.core.xdebug.XDebugResponse; /** * @author Christian * */ -public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugEventSetListener{ - // associated system process (VM) +public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugEventSetListener, IProxyEventListener { private IProcess fProcess; - - // containing launch object + private ILaunch fLaunch; - - // debugPort + private int fDebugPort; - - // program name -// private String fName; - - - // suspend state - private boolean fSuspended = true; - - // terminated state + + private boolean fSuspended = false; + private boolean fTerminated = false; - - // threads + private XDebugThread fThread; private IThread[] fThreads; - - // event dispatch job -// private EventDispatchJob fEventDispatch; - - private DebugConnection fDebugConnection; -// private DebugResponse lastResponse; + private XDebugConnection fDebugConnection; + + private ResponseListener fResponseListener; + + private String fIdeKey; - /** - * Constructs a new debug target in the given launch for the - * associated PDA VM process. - * + * Constructs a new debug target in the given launch and waits until + * someone with the ideKey connects to the Debugproxy + * + * * @param launch containing launch - * @param debugPort port to read events from + * @param process process of the interpreter + * @param ideKey * @exception CoreException if unable to connect to host */ - public XDebugTarget(ILaunch launch, IProcess process, int debugPort) throws CoreException { - super(null); + public XDebugTarget(ILaunch launch, IProcess process, String ideKey) throws CoreException { fLaunch = launch; fProcess = process; - fTarget = this; - fDebugConnection= new DebugConnection(this,debugPort); - fThread = new XDebugThread(this); - fThreads = new IThread[] {fThread}; + fDebugConnection = null; + fThread = null; + fThreads = new IThread[0]; + fIdeKey = ideKey; + + fDebugPort = XDebugCorePlugin.getDefault().getPreferenceStore().getInt(IXDebugPreferenceConstants.DEBUGPORT_PREFERENCE); + if (fDebugPort == 0) { + fDebugPort = IXDebugPreferenceConstants.DEFAULT_DEBUGPORT; + } + DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this); DebugPlugin.getDefault().addDebugEventListener(this); } + + public Object getAdapter(Class arg0) { + if (IWorkbenchAdapter.class.equals(arg0)) { + return new IWorkbenchAdapter() { + public Object[] getChildren(Object o) { + Object[] children = null; + IThread[] threads = getThreads(); + if (null != threads) { + children = new Object[threads.length]; + for (int i = 0; i < threads.length; ++i) + children[i] = threads[i]; + } + return children; + } + + public ImageDescriptor getImageDescriptor(Object object) { + return null; + } + + public String getLabel(Object o) { + String label = "(Unable to look up name... check error log)"; + try { + label = getName(); + } catch (DebugException x) { + PHPeclipsePlugin.log(label, x); + } + return label; + } + + public Object getParent(Object o) { + return XDebugTarget.this.getLaunch(); + } + }; + } + else { + if (arg0 == XDebugElement.class) { + return this; + } + + return super.getAdapter(arg0); + } + } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDebugTarget#getProcess() */ public IProcess getProcess() { return fProcess; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDebugTarget#getThreads() */ - public IThread[] getThreads() throws DebugException { + public IThread[] getThreads() { return fThreads; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDebugTarget#hasThreads() */ public boolean hasThreads() throws DebugException { - return (fThreads.length>0); + return (fThreads.length > 0); } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDebugTarget#getName() */ public String getName() throws DebugException { return "PHP XDebug Client at localhost:" + fDebugPort; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(org.eclipse.debug.core.model.IBreakpoint) */ public boolean supportsBreakpoint(IBreakpoint breakpoint) { - if (breakpoint.getModelIdentifier().equals(IXDebugConstants.ID_PHP_DEBUG_MODEL)) { + if (breakpoint.getModelIdentifier().equals(IXDebugConstants.ID_PHP_BREAKPOINT_MODEL)) { return true; } return false; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() */ public IDebugTarget getDebugTarget() { return this; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() */ public ILaunch getLaunch() { return fLaunch; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.ITerminate#canTerminate() */ public boolean canTerminate() { - return getProcess().canTerminate(); -// return false; + if (getProcess()!=null) // ther is no running Process in remote debugging + return getProcess().canTerminate(); + return true; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.ITerminate#isTerminated() */ @@ -144,89 +211,166 @@ public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugE // return getProcess().isTerminated(); return fTerminated; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.ITerminate#terminate() */ public void terminate() throws DebugException { - fDebugConnection.sendRequest ("stop"); + if(fTerminated) { + return; + } + + if (XDebugCorePlugin.getDefault() != null) { + XDebugProxy proxy = XDebugCorePlugin.getDefault().getXDebugProxy(); + proxy.removeProxyEventListener(this, fIdeKey); + + System.out.println("XDebug.Target: ProxyEventlistener removed"); + + fTerminated = true; + fSuspended = false; + + XDebugCorePlugin.getBreakpointManager().removeBreakpointListener(this); + fireEvent(new DebugEvent(this, DebugEvent.TERMINATE)); + DebugPlugin.getDefault().removeDebugEventListener(this); + } } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#canResume() */ public boolean canResume() { - return !isTerminated() && isSuspended(); + return false; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend() */ public boolean canSuspend() { - return !isTerminated() && !isSuspended(); + return false; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended() */ public boolean isSuspended() { return fSuspended; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#resume() */ public void resume() throws DebugException { - fDebugConnection.sendRequest("run"); + if (fDebugConnection != null) { + fThread.setBreakpoints(null); + resumed(DebugEvent.RESUME); + fDebugConnection.run(); + } } - + /** * Notification the target has resumed for the given reason - * + * * @param detail reason for the resume */ private void resumed(int detail) { fSuspended = false; fThread.fireResumeEvent(detail); } - + /** * Notification the target has suspended for the given reason - * + * * @param detail reason for the suspend */ public void suspended(int detail) { fSuspended = true; fThread.fireSuspendEvent(detail); - } - + } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#suspend() */ public void suspend() throws DebugException { } + /* (non-Javadoc) * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint) */ public void breakpointAdded(IBreakpoint breakpoint) { - - if (supportsBreakpoint(breakpoint)) { - try { - if (breakpoint.isEnabled()) { - IMarker marker = breakpoint.getMarker(); - if (marker != null) { + IMarker marker = breakpoint.getMarker(); // Get the breakpoints marker info (It's the local workspace path) + IPath path = marker.getResource().getLocation(); // Get the full path + file for the given breakpoint (It's the local real path) + IPath cp = path.removeLastSegments(1); // Get the full path only (without the file name) + List pathMap = null; + + try { + pathMap = fLaunch.getLaunchConfiguration().getAttribute(IXDebugConstants.ATTR_PHP_PATHMAP,(List)null); + } catch (CoreException e2) { + // TODO Auto-generated catch block + e2.printStackTrace(); + } + + if ((fDebugConnection != null) && // If there is a connection to XDebug + (!fDebugConnection.isClosed ()) && // and this connection is not closed + (fProcess == null)) { // + PathMapItem pmi = null; + + for (int i = 0; i < pathMap.size(); i++) { // For every path map pair the user have set + pmi = new PathMapItem((String) pathMap.get(i)); // Get the path map pair + IPath local = (IPath)pmi.getLocalPath().clone(); // Get the local + local = local.makeAbsolute(); + int matchedSegments = local.segmentCount(); + + if (local.matchingFirstSegments(cp) == matchedSegments) { + IPath newPath = pmi.getRemotePath(); + newPath = newPath.append(path.removeFirstSegments(matchedSegments)); + newPath = newPath.makeAbsolute(); + + if (supportsBreakpoint(breakpoint)) { try { - String fileName = PHPDebugUtils.escapeString(marker.getResource().getLocation().toString()); - String arg="-t line -f file:///"+fileName+" -n "+((ILineBreakpoint)breakpoint).getLineNumber(); - int id =fDebugConnection.sendRequest("breakpoint_set",arg); - // set the marker Attribute to make later idetification possible -// TODO: make sure that attribute is set before response from debugger is beeing prosessed - marker.setAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,id); - + if (breakpoint.isEnabled()) { + if (marker != null) { + int id = fDebugConnection.breakpointSet(newPath.toString(), ((ILineBreakpoint)breakpoint).getLineNumber(), marker.getAttribute(XDebugBreakpoint.HIT_COUNT,-1)); + XDebugResponse dr = getResponse(id); + + String bpid = dr.getAttributeValue("id"); + + if (!"".equals(bpid)) + marker.setAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,Integer.parseInt(bpid)); + } + } + } catch (DebugException e) { + e.printStackTrace(); } catch (CoreException e) { + e.printStackTrace(); } } } - } catch (CoreException e) { + } + } else { + if (supportsBreakpoint(breakpoint)) { + try { + if (breakpoint.isEnabled()) { + if (marker != null) { + int id = fDebugConnection.breakpointSet (path.toString(), + ((ILineBreakpoint) breakpoint).getLineNumber(), + marker.getAttribute (XDebugBreakpoint.HIT_COUNT, -1)); + XDebugResponse dr = getResponse(id); + String bpid = dr.getAttributeValue("id"); + if (!"".equals(bpid)) { + marker.setAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,Integer.parseInt(bpid)); + } + } + } + } catch (DebugException e) { + e.printStackTrace(); + } catch (CoreException e) { + e.printStackTrace(); + } } } } + /* (non-Javadoc) * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta) */ @@ -235,11 +379,12 @@ public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugE try { int id =((XDebugLineBreakpoint)breakpoint).getID(); if (id >0) - fDebugConnection.sendRequest("breakpoint_remove","-d "+id); + fDebugConnection.breakpointRemove(id); } catch (CoreException e) { } } } + /* (non-Javadoc) * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta) */ @@ -255,29 +400,34 @@ public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugE // } // } } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect() */ public boolean canDisconnect() { return false; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDisconnect#disconnect() */ public void disconnect() throws DebugException { } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected() */ public boolean isDisconnected() { - return false; + return (false); } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval() */ public boolean supportsStorageRetrieval() { return false; } + /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long) */ @@ -286,22 +436,41 @@ public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugE } /** - * Notification we have connected to the PHP debugger and it has started. + * Notification we have connected to the PHP debugger and it has been started. * Resume the the debugger. */ - public void started() { - + public void started() throws DebugException { fThread.setBreakpoints(null); fThread.setStepping(false); + int id = fDebugConnection.featureGet("detach"); + + XDebugResponse response = getResponse(id); + + Integer.parseInt(response.getValue()); + System.out.println("in Target.started()"); + + // Dirty hack + // Need to refactory plugin to get variables in lazy mode. + int id1 = fDebugConnection.featureSet("max_depth", "1024" ); + XDebugResponse response1 = getResponse(id1); + if (response1.getAttributeValue("success").equals("1") ) { + System.out.println("Set depth to 1024 (hack)"); + } + int id2 = fDebugConnection.featureSet("max_children", "1024" ); + XDebugResponse response2 = getResponse(id2); + if (response2.getAttributeValue("success").equals("1") ) { + System.out.println("Set children to 1024 (hack)"); + } + installDeferredBreakpoints(); try { resume(); -// step(); } catch (DebugException e) { + e.printStackTrace(); } } - + /** * Install breakpoints that are already registered with the breakpoint * manager. @@ -312,198 +481,286 @@ public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugE breakpointAdded(breakpoints[i]); } } - - /** - * Called when this debug target terminates. - */ - public void terminated() { - fTerminated = true; - fSuspended = false; - XDebugCorePlugin.getBreakpointManager().removeBreakpointListener(this); - fireTerminateEvent(); - DebugPlugin.getDefault().removeDebugEventListener(this); - fThread.removeEventListeners(); - } - + /** * Returns the current stack frames in the target. - * + * * @return the current stack frames in the target * @throws DebugException if unable to perform the request */ - protected IStackFrame[] getStackFrames() throws DebugException { - int id=fDebugConnection.sendRequest("stack_get"); - DebugResponse lastResponse=fDebugConnection.waitforTransID(id); - if (lastResponse.isError()) - return new IStackFrame[0]; - Node response = lastResponse.getParentNode(); - NodeList frames = response.getChildNodes(); - IStackFrame[] theFrames = new IStackFrame[frames.getLength()]; - for (int i = 0; i < frames.getLength(); i++) { - Node stackNode = frames.item(i); - theFrames[i] = new XDebugStackFrame(fThread, stackNode, i); - } - return theFrames; + public XDebugResponse getStackFrames() throws DebugException { + int id = fDebugConnection.stackGet(); + XDebugResponse lastResponse = getResponse(id); + return lastResponse; } - + /** * Single step the interpreter. - * + * * @throws DebugException if the request fails */ protected void step_over() throws DebugException { fThread.setStepping(true); resumed(DebugEvent.STEP_OVER); - fDebugConnection.sendRequest("step_over"); + fDebugConnection.stepOver(); } - + /** * Single step the interpreter. - * + * * @throws DebugException if the request fails */ protected void step_into() throws DebugException { fThread.setStepping(true); resumed(DebugEvent.STEP_INTO); - fDebugConnection.sendRequest("step_into"); + fDebugConnection.stepInto(); } - + /** * Single step the interpreter. - * + * * @throws DebugException if the request fails */ protected void step_out() throws DebugException { fThread.setStepping(true); resumed(DebugEvent.STEP_RETURN); - fDebugConnection.sendRequest("step_out"); + fDebugConnection.stepOut(); } + public boolean setVarValue(String name, String value) { + int id = fDebugConnection.setVarValue(name,value); + XDebugResponse response = getResponse(id); - - /** - * Returns the current value of the given variable. - * - * @param variable - * @return variable value - * @throws DebugException if the request fails - */ - protected IValue getVariableValue(XDebugVariable variable) throws DebugException { -// synchronized (fDebugSocket) { -// fDebugConnection.sendRequest("var","" + variable.getStackFrame().getIdentifier() + " " + variable.getName()); -// try { -// String value = fDebugReader.readLine(); -// //return new XDebugValue(this, value); -// -// } catch (IOException e) { -// abort(MessageFormat.format("Unable to retrieve value for variable {0}", new String[]{variable.getName()}), e); -// } -// } - return null; + if ((response.getAttributeValue("success")).equals("1")) { + return true; + } else { + return false; + } } - - /** - * Returns the values on the data stack (top down) - * - * @return the values on the data stack (top down) - */ - public IValue[] getDataStack() throws DebugException { -// synchronized (fDebugSocket) { -// fDebugConnection.sendRequest ("data"); -// try { -// String valueString = fDebugReader.readLine(); -// if (valueString != null && valueString.length() > 0) { -// String[] values = valueString.split("\\|"); -// IValue[] theValues = new IValue[values.length]; -// for (int i = 0; i < values.length; i++) { -// String value = values[values.length - i - 1]; -//// theValues[i] = new XDebugValue(this, value); -// } -// return theValues; -// } -// } catch (IOException e) { -// abort("Unable to retrieve data stack", e); -// } -// } - return new IValue[0]; + + public Node eval(String expression) throws DebugException { + Node evalProperty = null; + if (fDebugConnection != null) { + int id = fDebugConnection.eval(expression); + //Node evalProperty = new Node(""); + //if (id > 0) { + XDebugResponse response = getResponse(id); + + Node evalResponse = response.getParentNode(); + /*Node*/ evalProperty = evalResponse.getFirstChild(); + //} /*else { + + //}*/ + } else { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + Document doc = null; + + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + //try { + doc = builder.newDocument(); // .parse(""); + evalProperty = doc.createElement("value"); + /*} catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + }*/ + } + + return evalProperty; } - - public boolean setVarValue(String name, String value) { - int id=-1; - String str=Base64.encodeBytes(value.getBytes()); - int len=str.length(); - try { - id =fDebugConnection.sendRequest("property_set","-n "+name+" -l "+len + " -- "+str); - } catch (DebugException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + public void handleDebugEvents(DebugEvent[] events) { + for (int i = 0; i < events.length; i++) { + DebugEvent event = events[i]; + + if (fResponseListener != null) { + Object s = null; + s = event.getSource(); + if (s instanceof ResponseListener) { + if (!fResponseListener.equals((ResponseListener) s)) { + return; + } + } + } else { + return; + } + + if (event.getKind() == DebugEvent.MODEL_SPECIFIC) { + switch (event.getDetail()) { + case IPHPDebugEvent.BREAKPOINT_HIT: + int id = fDebugConnection.stackGet(); + XDebugResponse lastResponse = getResponse(id); + + IBreakpoint breakpoint = breakpointHit(lastResponse.getParentNode()); + + if (breakpoint != null) { + fThread.setBreakpoints(new IBreakpoint[]{breakpoint}); + fThread.incrementStepCounter(); + suspended(DebugEvent.BREAKPOINT); + } else { + try { + resume(); + } catch (DebugException e ) { + ; //nothing to do + } + } + break; + case IPHPDebugEvent.STEP_END: + fThread.incrementStepCounter(); + suspended(DebugEvent.STEP_END); + break; + case IPHPDebugEvent.STOPPED: + stopped(); + break; + } + } } - DebugResponse dr=getResponse(id); - if ((dr.getAttributeValue("success")).equals("1")) - return true; - - return false; } - - public DebugResponse getResponse(int id) { - return fDebugConnection.waitforTransID(id); + + public void stopped() { + if(fDebugConnection == null) { + return; + } + + resumed(DebugEvent.TERMINATE); + + stopListener(); + fDebugConnection.close(); + + fSuspended = false; + + // Dirty hack to check debugging mode (remote or local) + if (fProcess != null) { + try { + terminate(); + } catch (DebugException e) { + e.printStackTrace(); + } + } else { + fDebugConnection = null; + fireEvent(new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CONTENT)); + } + + fThread.removeEventListeners(); + fThread = null; + fThreads = new IThread[0]; } - /** - * Sends a request to the Debugengine and waits for an OK. - * - * @param command debug command - * @throws DebugException if the request fails - */ - - public int sendRequest(String command) throws DebugException { - return fDebugConnection.sendRequest(command,""); + public void handleProxyEvent(XDebugConnection connection) { + //System.out.println("* New Connection - XDebug.Target: " + fDebugConnection.getSessionID()); + + if (setDebugConnection(connection)) { + fThread = new XDebugThread(this); + fThreads = new IThread[] {fThread}; + fireEvent(new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CHANGE)); + try { + started(); + } catch( DebugException e ){ + e.printStackTrace(); + } + } + } + + private boolean setDebugConnection(XDebugConnection connection) { + if (connection != null && fDebugConnection == null) { + fDebugConnection = connection; + fResponseListener = new ResponseListener(connection); + startListener(); + + return true; + } else { + connection.close(); + + return false; + } } - /** - * Sends a request to the Debugengine and waits for an OK. - * - * @param command debug command - * @arguments arguments for the command - * @throws DebugException if the request fails + * @return Returns the fDebugConnection. */ - - public int sendRequest(String command, String arguments) throws DebugException { - return fDebugConnection.sendRequest(command,arguments); + public XDebugConnection getDebugConnection() { + return fDebugConnection; } - - /** - * Notification a breakpoint was encountered. Determine - * which breakpoint was hit and fire a suspend event. - * - * @param event debug event - */ - public void breakpointHit(Node node) { - // determine which breakpoint was hit, and set the thread's breakpoint - Node child=node.getFirstChild(); + + public void addProcess(IProcess p) { + fProcess = p; + + } + public Node getLocalVariables(int level) throws DebugException { + int id = fDebugConnection.contextGet(level, 0); + XDebugResponse response = getResponse(id); + + return response.getParentNode(); + } + + public Node getGlobalVariables(int level) throws DebugException { + int id = fDebugConnection.contextGet(level, 1); + XDebugResponse response = getResponse(id); + + return response.getParentNode(); + } + + public void stop() { + fDebugConnection.stop(); + } + + protected IBreakpoint breakpointHit(Node node) { + Node child = node.getFirstChild(); if (child.getNodeName().equals("stack")) { int lineNumber = Integer.parseInt(PHPDebugUtils.getAttributeValue(child, "lineno")); - String filename=PHPDebugUtils.getAttributeValue(child, "filename").substring(8); // remove file:/// + String filename = PHPDebugUtils.getAttributeValue(child, "filename"); IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints(); for (int i = 0; i < breakpoints.length; i++) { IBreakpoint breakpoint = breakpoints[i]; if (supportsBreakpoint(breakpoint)) { if (breakpoint instanceof ILineBreakpoint) { ILineBreakpoint lineBreakpoint = (ILineBreakpoint) breakpoint; - try { + try { if (breakpoint.isEnabled()) { IMarker marker = breakpoint.getMarker(); if (marker != null) { + String endfilename; + + if (getProcess() == null) { + endfilename = marker.getResource().getLocation().lastSegment(); + } else { + endfilename = marker.getResource().getLocation().toOSString(); + } + + int id = fDebugConnection.breakpointGet(marker.getAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,-1)); + XDebugResponse dr = getResponse(id); + + Node hitCo = dr.getParentNode().getFirstChild(); + int hitCount = 0; + if (hitCo.hasAttributes()) { + NamedNodeMap listAttribute = hitCo.getAttributes(); + Node attribute = listAttribute.getNamedItem("hit_count"); + if (attribute !=null) { + hitCount = Integer.parseInt(attribute.getNodeValue()); + } + } - String name = marker.getResource().getLocation().toOSString(); - if(name.equals(PHPDebugUtils.unescapeString(filename)) && (lineBreakpoint.getLineNumber() == lineNumber)) { - fThread.setBreakpoints(new IBreakpoint[]{breakpoint}); - break; + Path path1 = new Path (PHPDebugUtils.unescapeString (filename)); + Path path2 = new Path (endfilename); + + if (path1.toString ().endsWith (path2.toString ()) +// if (strPath1.endsWith (strPath2) + //if(PHPDebugUtils.unescapeString(filename).endsWith(endfilename) + && (lineBreakpoint.getLineNumber() == lineNumber) ) { + if (marker.getAttribute(XDebugLineBreakpoint.HIT_COUNT, 0) > 0) { + if (marker.getAttribute(XDebugLineBreakpoint.HIT_COUNT, 0) == hitCount) { + return (breakpoint); + } + } else { + return (breakpoint); + } } } - } } catch (CoreException e) { } @@ -511,18 +768,20 @@ public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugE } } } - suspended(DebugEvent.BREAKPOINT); + + return null; } - public void handleDebugEvents(DebugEvent[] events) { - for (int i=0;i