d700859a54725decfc06d4dbcd9817da075b1a6c
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / core / xdebug / ResponseListener.java
1 package net.sourceforge.phpeclipse.xdebug.core.xdebug;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5
6 import javax.xml.parsers.DocumentBuilder;
7 import javax.xml.parsers.DocumentBuilderFactory;
8 import javax.xml.parsers.ParserConfigurationException;
9
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;
17
18 import org.eclipse.core.runtime.IPath;
19 import org.eclipse.core.runtime.Path;
20
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;
37
38 /**
39  * Listens to events from the XDebug and fires corresponding 
40  * debug events.
41  */
42
43 public class ResponseListener extends Job {
44         
45
46         public class DebugResponse {
47
48                         private Node parentNode;
49                         private int fTransactionID=-1;
50                         private String fCommand="";
51                         private String fStatus;
52                         private String fReason;
53                         private String fName;
54                         private boolean  fError;
55
56                         private String fValue;
57                         private String fType;
58                         private String fAddress;
59                         
60                         public synchronized void setParentNode (String xmlInput){
61                                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
62                                 DocumentBuilder builder=null;
63                                 Document doc=null;
64                                 try {
65                                         builder = factory.newDocumentBuilder();
66                                 } catch (ParserConfigurationException e) {
67                                         // TODO Auto-generated catch block
68                                         e.printStackTrace();
69                                 }
70                                 ByteArrayInputStream InputXMLStream = new ByteArrayInputStream(xmlInput.getBytes());
71                                 
72                                 try {
73                                         doc = builder.parse(InputXMLStream);
74                                 } catch (SAXException e) {
75                                         // TODO Auto-generated catch block
76                                         e.printStackTrace();
77                                 } catch (IOException e) {
78                                         // TODO Auto-generated catch block
79                                         e.printStackTrace();
80                                 }
81                                 
82
83                                 parentNode=doc.getFirstChild();
84                                 
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");
92
93                                 if( fCommand.compareTo("eval") == 0 ) {
94                                         try {
95                                                 Node property = parentNode.getFirstChild();
96
97                                                 NamedNodeMap listAttribute = property.getAttributes();
98                                                 Node attribute = listAttribute.getNamedItem("type");
99                                                 if (attribute !=null) {
100                                                         fType = attribute.getNodeValue();
101                                                 }
102
103                                                 Node attribute1 = listAttribute.getNamedItem("address");
104                                                 if (attribute1 !=null) {
105                                                         fAddress = attribute1.getNodeValue();
106                                                 }
107                                                 
108                                                 Node firstChild1 = (Node) property.getFirstChild();
109                                                 
110                                                 if( firstChild1 != null ) {
111                                                         fValue = firstChild1.getNodeValue();
112                                                 }
113                                         } catch (Exception e) {
114                                                 // TODO: handle exception
115                                         }
116                                 } else {
117                                         try {
118                                                 CDATASection firstChild = (CDATASection) parentNode.getFirstChild();
119                 
120                                                 if( firstChild != null ) {
121                                                         fValue = parentNode.getFirstChild().getNodeValue();
122                                                 }
123                                         } catch (Exception e) {
124                                                 // TODO: handle exception
125                                         }
126                                 }
127                         }
128                         
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();
136                                 }
137                                 return strValue;
138                         }
139                         
140                         public synchronized Node getParentNode(){
141                                 return parentNode;
142                         }
143                         
144                         public synchronized String getCommand() {
145                                 return fCommand;
146                         }
147                         public synchronized String getName() {
148                                 return fName;
149                         }
150                         
151                         public synchronized String getValue() {
152                                 return fValue;
153                         }
154
155                         public synchronized String getType() {
156                                 return fType;
157                         }
158
159                         public synchronized String getAddress() {
160                                 return fAddress;
161                         }
162
163                         DebugResponse () {
164                                 fTransactionID = -1;
165                                 fCommand = "";
166                                 fStatus = "";
167                                 fReason = "";                   
168                                 fName= "";
169                         }
170                         
171                         DebugResponse (String XMLInput) {
172                                 setParentNode(XMLInput);
173                         }
174
175                         public synchronized String getReason() {
176                                 return fReason;
177                         }
178
179                         public synchronized String getStatus() {
180                                 return fStatus;
181                         }
182
183                         public synchronized int getTransactionID() {
184                                 return fTransactionID;
185                         }
186                         
187                         public boolean  isError() {
188                                 return fError;
189                         }
190
191                         public void setError(boolean error) {
192                                 fError = error;
193                         }
194                         
195                 }
196
197         
198         private XDebugConnection fConnection;
199         //private XDebugTarget fDebugTarget;
200         private DebugResponse lastResponse; 
201
202         public ResponseListener(XDebugConnection connection) {
203                 super("XDebug Event Dispatch");
204                 setSystem(true);
205                 fConnection=connection;
206                 lastResponse= new DebugResponse();
207         }
208         
209         
210         
211         
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);
221                                 return;
222                         }
223                 }
224                 lastResponse.setError(false);
225                 if (response.getStatus().equals("stopping")) {
226                 //if (response.getStatus().equals("stopped")) {
227                         fConnection.close();
228                         fireEvent(IPHPDebugEvent.STOPPED);
229                 } else if (response.getStatus().equals("break") && response.getReason().equals("ok")){ 
230                         if (response.getCommand().equals("run")) {  // breakpoint hit
231                                 int id=-1;
232                                 try {
233                                         id=fConnection.sendRequest("stack_get");
234                                 } catch (DebugException e) {
235                                         // TODO Auto-generated catch block
236                                         e.printStackTrace();
237                                 }
238                                 String InputXML = fConnection.readData();
239                                 if (InputXML != null) {
240                                         XDebugCorePlugin.log(IStatus.INFO, InputXML);
241                                         lastResponse.setParentNode(InputXML);
242                                         breakpointHit(lastResponse.getParentNode());
243                                 }
244                                 
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");
254                         } 
255                 } 
256
257         }
258         
259         protected void fireEvent(int detail) {
260                 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
261                 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
262         }
263         
264         protected void fireEvent(int detail, Object data) {
265                 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
266                 event.setData(data);
267                 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
268         }
269
270         
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;
282                                                 try {                                           
283                                                         if (breakpoint.isEnabled()) {
284                                                                 IMarker marker = breakpoint.getMarker();
285                                                                 if (marker != null) {
286                                                                         String endfilename;
287                                                                         
288                                                                         if( XDebugCorePlugin.getDefault().getXDebugProxy().getTarget().getProcess() == null ) {
289                                                                                 endfilename = marker.getResource().getLocation().lastSegment(); 
290                                                                         } else {
291                                                                                 endfilename = marker.getResource().getLocation().toOSString();
292                                                                         }
293
294                                                                         if(PHPDebugUtils.unescapeString(filename).endsWith(endfilename) && (lineBreakpoint.getLineNumber() == lineNumber) ) {
295                                                                                 fireEvent(IPHPDebugEvent.BREAKPOINT_HIT,breakpoint);
296                                                                                 break;
297                                                                         }
298                                                                 }
299                                                         }
300                                                 } catch (CoreException e) {
301                                                 }
302                                         }
303                                 }
304                         }
305                 }
306
307 //              DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, IPHPDebugEvent.STEP_END);
308 //              DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
309         }
310         
311         private boolean supportsBreakpoint(IBreakpoint breakpoint) {
312                 if (breakpoint.getModelIdentifier().equals(IXDebugConstants.ID_PHP_DEBUG_MODEL)) {
313                         return true;
314                 }
315                 return false;
316         }
317
318
319         
320         /* (non-Javadoc)
321          * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
322          */
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);
339                                 }
340 //                              fConnection.addResponse(lastResponse,lastResponse.getTransactionID());
341 //                              lastResponse.notifyWait();
342                         }
343                 }
344                 return Status.OK_STATUS;
345         }
346         
347 }