1 package net.sourceforge.phpeclipse.xdebug.core.xdebug;
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
6 import javax.xml.parsers.DocumentBuilder;
7 import javax.xml.parsers.DocumentBuilderFactory;
8 import javax.xml.parsers.ParserConfigurationException;
10 import net.sourceforge.phpeclipse.xdebug.core.IPHPDebugEvent;
11 import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils;
12 import net.sourceforge.phpeclipse.xdebug.core.PathMapItem;
13 import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
14 import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants;
15 import net.sourceforge.phpeclipse.xdebug.php.model.XDebugLineBreakpoint;
16 import net.sourceforge.phpeclipse.xdebug.php.model.XDebugTarget;
18 import org.eclipse.core.runtime.IPath;
19 import org.eclipse.core.runtime.Path;
21 import org.eclipse.core.resources.IMarker;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.Status;
26 import org.eclipse.core.runtime.jobs.Job;
27 import org.eclipse.debug.core.DebugEvent;
28 import org.eclipse.debug.core.DebugException;
29 import org.eclipse.debug.core.DebugPlugin;
30 import org.eclipse.debug.core.model.IBreakpoint;
31 import org.eclipse.debug.core.model.ILineBreakpoint;
32 import org.w3c.dom.Document;
33 import org.w3c.dom.NamedNodeMap;
34 import org.w3c.dom.Node;
35 import org.xml.sax.SAXException;
36 import org.w3c.dom.CDATASection;
39 * Listens to events from the XDebug and fires corresponding
43 public class ResponseListener extends Job {
46 public class DebugResponse {
48 private Node parentNode;
49 private int fTransactionID=-1;
50 private String fCommand="";
51 private String fStatus;
52 private String fReason;
54 private boolean fError;
56 private String fValue;
58 private String fAddress;
60 public synchronized void setParentNode (String xmlInput){
61 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
62 DocumentBuilder builder=null;
65 builder = factory.newDocumentBuilder();
66 } catch (ParserConfigurationException e) {
67 // TODO Auto-generated catch block
70 ByteArrayInputStream InputXMLStream = new ByteArrayInputStream(xmlInput.getBytes());
73 doc = builder.parse(InputXMLStream);
74 } catch (SAXException e) {
75 // TODO Auto-generated catch block
77 } catch (IOException e) {
78 // TODO Auto-generated catch block
83 parentNode=doc.getFirstChild();
85 fName=parentNode.getNodeName();
86 String idStr = getAttributeValue("transaction_id");
87 if (!"".equals(idStr))
88 fTransactionID = Integer.parseInt(idStr);
89 fCommand = getAttributeValue("command");
90 fStatus = getAttributeValue("status");
91 fReason = getAttributeValue("reason");
93 if( fCommand.compareTo("eval") == 0 ) {
95 Node property = parentNode.getFirstChild();
97 NamedNodeMap listAttribute = property.getAttributes();
98 Node attribute = listAttribute.getNamedItem("type");
99 if (attribute !=null) {
100 fType = attribute.getNodeValue();
103 Node attribute1 = listAttribute.getNamedItem("address");
104 if (attribute1 !=null) {
105 fAddress = attribute1.getNodeValue();
108 Node firstChild1 = (Node) property.getFirstChild();
110 if( firstChild1 != null ) {
111 fValue = firstChild1.getNodeValue();
113 } catch (Exception e) {
114 // TODO: handle exception
118 CDATASection firstChild = (CDATASection) parentNode.getFirstChild();
120 if( firstChild != null ) {
121 fValue = parentNode.getFirstChild().getNodeValue();
123 } catch (Exception e) {
124 // TODO: handle exception
129 public String getAttributeValue (String AttributeName) {
130 String strValue = "";
131 if (parentNode.hasAttributes()) {
132 NamedNodeMap listAttribute = parentNode.getAttributes();
133 Node attribute = listAttribute.getNamedItem(AttributeName);
134 if (attribute !=null)
135 strValue = attribute.getNodeValue();
140 public synchronized Node getParentNode(){
144 public synchronized String getCommand() {
147 public synchronized String getName() {
151 public synchronized String getValue() {
155 public synchronized String getType() {
159 public synchronized String getAddress() {
171 DebugResponse (String XMLInput) {
172 setParentNode(XMLInput);
175 public synchronized String getReason() {
179 public synchronized String getStatus() {
183 public synchronized int getTransactionID() {
184 return fTransactionID;
187 public boolean isError() {
191 public void setError(boolean error) {
198 private XDebugConnection fConnection;
199 //private XDebugTarget fDebugTarget;
200 private DebugResponse lastResponse;
202 public ResponseListener(XDebugConnection connection) {
203 super("XDebug Event Dispatch");
205 fConnection=connection;
206 lastResponse= new DebugResponse();
212 private void checkResponse(DebugResponse response) {
213 Node node=response.getParentNode();
214 if (node.hasChildNodes()) {
215 Node child=node.getFirstChild();
216 if (child.getNodeName().equals("error")) {
217 int code = Integer.parseInt(PHPDebugUtils.getAttributeValue(child, "code"));
218 String text=(child.getFirstChild()).getNodeValue();
219 XDebugCorePlugin.log(IStatus.ERROR," ERROR "+code+": "+text);
220 lastResponse.setError(true);
224 lastResponse.setError(false);
225 if (response.getStatus().equals("stopping")) {
226 //if (response.getStatus().equals("stopped")) {
228 fireEvent(IPHPDebugEvent.STOPPED);
229 } else if (response.getStatus().equals("break") && response.getReason().equals("ok")){
230 if (response.getCommand().equals("run")) { // breakpoint hit
233 id=fConnection.sendRequest("stack_get");
234 } catch (DebugException e) {
235 // TODO Auto-generated catch block
238 String InputXML = fConnection.readData();
239 if (InputXML != null) {
240 XDebugCorePlugin.log(IStatus.INFO, InputXML);
241 lastResponse.setParentNode(InputXML);
242 breakpointHit(lastResponse.getParentNode());
245 } else if (response.getCommand().equals("step_into")) { // step_into
246 fireEvent(IPHPDebugEvent.STEP_END);
247 // XDebugCorePlugin.log(IStatus.INFO,response.getCommand()+" STEP_END sent");
248 } else if (response.getCommand().equals("step_over")) { // step_over
249 fireEvent(IPHPDebugEvent.STEP_END);
250 // XDebugCorePlugin.log(IStatus.INFO,response.getCommand()+" STEP_END sent");
251 } else if (response.getCommand().equals("step_out")) { // step_over
252 fireEvent(IPHPDebugEvent.STEP_END);
253 // XDebugCorePlugin.log(IStatus.INFO,response.getCommand()+" STEP_END sent");
259 protected void fireEvent(int detail) {
260 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
261 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
264 protected void fireEvent(int detail, Object data) {
265 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
267 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
271 protected void breakpointHit(Node node) {
272 Node child=node.getFirstChild();
273 if (child.getNodeName().equals("stack")) {
274 int lineNumber = Integer.parseInt(PHPDebugUtils.getAttributeValue(child, "lineno"));
275 String filename=PHPDebugUtils.getAttributeValue(child, "filename");
276 IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints();
277 for (int i = 0; i < breakpoints.length; i++) {
278 IBreakpoint breakpoint = breakpoints[i];
279 if (supportsBreakpoint(breakpoint)) {
280 if (breakpoint instanceof ILineBreakpoint) {
281 ILineBreakpoint lineBreakpoint = (ILineBreakpoint) breakpoint;
283 if (breakpoint.isEnabled()) {
284 IMarker marker = breakpoint.getMarker();
285 if (marker != null) {
288 if( XDebugCorePlugin.getDefault().getXDebugProxy().getTarget().getProcess() == null ) {
289 endfilename = marker.getResource().getLocation().lastSegment();
291 endfilename = marker.getResource().getLocation().toOSString();
294 if(PHPDebugUtils.unescapeString(filename).endsWith(endfilename) && (lineBreakpoint.getLineNumber() == lineNumber) ) {
295 fireEvent(IPHPDebugEvent.BREAKPOINT_HIT,breakpoint);
300 } catch (CoreException e) {
307 // DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, IPHPDebugEvent.STEP_END);
308 // DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
311 private boolean supportsBreakpoint(IBreakpoint breakpoint) {
312 if (breakpoint.getModelIdentifier().equals(IXDebugConstants.ID_PHP_DEBUG_MODEL)) {
321 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
323 protected IStatus run(IProgressMonitor monitor) {
324 String InputXML = "";
325 while (!fConnection.isClosed() && (InputXML != null)) {
326 InputXML = fConnection.readData();
327 if (InputXML != null) {
328 XDebugCorePlugin.log(IStatus.INFO, InputXML);
329 lastResponse.setParentNode(InputXML);
330 // if (lastResponse.getName() == "init") {
331 // Node myNode=lastResponse.getParentNode();
332 // appID = PHPDebugUtils.getAttributeValue(myNode, "appid");
333 // fileuri = PHPDebugUtils.getAttributeValue(myNode, "fileuri");
334 // fDebugTarget.started();
335 // fDebugTarget.fireCreationEvent();
336 if (lastResponse.getName() == "response") {
337 fConnection.addResponse(lastResponse,lastResponse.getTransactionID());
338 checkResponse(lastResponse);
340 // fConnection.addResponse(lastResponse,lastResponse.getTransactionID());
341 // lastResponse.notifyWait();
344 return Status.OK_STATUS;