Merge xdebug from 1.3.x.
[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.print.attribute.standard.Fidelity;
7 import javax.xml.parsers.DocumentBuilder;
8 import javax.xml.parsers.DocumentBuilderFactory;
9 import javax.xml.parsers.ParserConfigurationException;
10
11 import net.sourceforge.phpeclipse.xdebug.core.IPHPDebugEvent;
12 import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils;
13 import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
14 import org.eclipse.core.runtime.IProgressMonitor;
15 import org.eclipse.core.runtime.IStatus;
16 import org.eclipse.core.runtime.Status;
17 import org.eclipse.core.runtime.jobs.Job;
18 import org.eclipse.debug.core.DebugEvent;
19 import org.eclipse.debug.core.DebugPlugin;
20 import org.w3c.dom.Document;
21 import org.w3c.dom.NamedNodeMap;
22 import org.w3c.dom.Node;
23 import org.xml.sax.SAXException;
24 import org.w3c.dom.CDATASection;
25
26 /**
27  * Listens to events from the XDebug and fires corresponding 
28  * debug events.
29  */
30
31 public class ResponseListener extends Job {
32         public class XDebugResponse {
33                 final public static String TYPE_INIT = "init";
34                 
35                 final public static String TYPE_RESPONSE = "response";
36                 
37                 final public static String TYPE_STREAM = "stream";
38
39                 private Node parentNode;
40                 private int fTransactionID = -1;
41                 private String fCommand = "";
42                 private String fStatus;
43                 private String fReason;
44                 private String fName;
45                 private boolean  fError;
46         
47                 private String fValue;
48                 private String fType;
49                 private String fAddress;
50                 private String fIdeKey;
51                         
52                 public synchronized void setParentNode(String xmlInput) {
53                         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
54                         DocumentBuilder builder = null;
55                         Document doc = null;
56                         
57                         try {
58                                 builder = factory.newDocumentBuilder();
59                         } catch (ParserConfigurationException e) {
60                                 e.printStackTrace();
61                         }
62                         ByteArrayInputStream InputXMLStream = new ByteArrayInputStream(xmlInput.getBytes());
63                         try {
64                                 doc = builder.parse(InputXMLStream);
65                         } catch (SAXException e) {
66                                 e.printStackTrace();
67                         } catch (IOException e) {
68                                 e.printStackTrace();
69                         }
70         
71                         parentNode = doc.getFirstChild();
72                         
73                         String responseType = parentNode.getNodeName();
74                         if (responseType == TYPE_INIT) {
75                                 fName = TYPE_INIT;
76                                 parseInit(parentNode);
77                         } else if (responseType == TYPE_RESPONSE) {
78                                 fName = TYPE_RESPONSE;
79                                 parseResponse(parentNode);
80                         } else if (responseType == TYPE_STREAM) {
81                                 fName = TYPE_STREAM;
82                                 parseStream();
83                         } else {
84                                 fName = null;
85                         }
86                 }
87                 
88                 private void parseInit(Node parentNode) {
89                         fIdeKey = getAttributeValue("idekey");
90                         
91                         /*int startIdx = initString.indexOf("idekey=\"");
92                         if (startIdx == -1)
93                                 return;
94                         startIdx += 8;
95                         int endIdx=initString.indexOf('"',startIdx);
96                         if (endIdx==-1)
97                                 return;
98                         fSessionID = initString.substring(startIdx,endIdx);*/
99                 }
100                 
101                 private void parseResponse(Node parentNode) {
102                         String idStr = getAttributeValue("transaction_id");
103                         if (!"".equals(idStr))
104                                 fTransactionID = Integer.parseInt(idStr);
105                         fCommand = getAttributeValue("command");
106                         if (parentNode.hasChildNodes()) {
107                                 Node child = parentNode.getFirstChild();
108                                 if (child.getNodeName().equals("error")) {
109                                         int code = Integer.parseInt(PHPDebugUtils.getAttributeValue(child, "code"));
110                                         String text = (child.getFirstChild()).getNodeValue();
111                                         XDebugCorePlugin.log(IStatus.ERROR," ERROR "+code+": "+text);
112                                         setError(true);
113                                         return;
114                                 }
115                         }
116                         setError(false);
117                         
118                         fStatus = getAttributeValue("status");
119                         fReason = getAttributeValue("reason");
120         
121                         if( fCommand.compareTo("eval") == 0 ) {
122                                 try {
123                                         Node property = parentNode.getFirstChild();
124         
125                                         NamedNodeMap listAttribute = property.getAttributes();
126                                         Node attribute = listAttribute.getNamedItem("type");
127                                         if (attribute !=null) {
128                                                 fType = attribute.getNodeValue();
129                                         }
130         
131                                         Node attribute1 = listAttribute.getNamedItem("address");
132                                         if (attribute1 !=null) {
133                                                 fAddress = attribute1.getNodeValue();
134                                         }
135                                         
136                                         Node firstChild1 = (Node) property.getFirstChild();
137                                         
138                                         if( firstChild1 != null ) {
139                                                 fValue = firstChild1.getNodeValue();
140                                         }
141                                 } catch (Exception e) {
142                                         // TODO: handle exception
143                                 }
144                         } else {
145                                 try {
146                                         CDATASection firstChild = (CDATASection) parentNode.getFirstChild();
147         
148                                         if( firstChild != null ) {
149                                                 fValue = parentNode.getFirstChild().getNodeValue();
150                                         }
151                                 } catch (Exception e) {
152                                 }
153                         }
154                         
155                 }
156                 
157                 private void parseStream() {
158                         
159                 }
160                 
161                 
162                 public String getAttributeValue (String AttributeName) {
163                         String strValue = "";
164                         if (parentNode.hasAttributes()) {
165                                 NamedNodeMap listAttribute = parentNode.getAttributes();
166                                 Node attribute = listAttribute.getNamedItem(AttributeName);
167                                 if (attribute !=null)
168                                         strValue = attribute.getNodeValue();
169                         }
170                         return strValue;
171                 }
172                 
173                 public synchronized Node getParentNode(){
174                         return parentNode;
175                 }
176                 
177                 public synchronized String getIdeKey(){
178                         return fIdeKey;
179                 }
180                 
181                 public synchronized String getCommand() {
182                         return fCommand;
183                 }
184                 public synchronized String getName() {
185                         return fName;
186                 }
187                 
188                 public synchronized String getValue() {
189                         return fValue;
190                 }
191         
192                 public synchronized String getType() {
193                         return fType;
194                 }
195         
196                 public synchronized String getAddress() {
197                         return fAddress;
198                 }
199         
200                 public XDebugResponse(String XMLInput) {
201                         setParentNode(XMLInput);
202                 }
203         
204                 public synchronized String getReason() {
205                         return fReason;
206                 }
207         
208                 public synchronized String getStatus() {
209                         return fStatus;
210                 }
211         
212                 public synchronized int getTransactionID() {
213                         return fTransactionID;
214                 }
215                 
216                 public boolean  isError() {
217                         return fError;
218                 }
219         
220                 public void setError(boolean error) {
221                         fError = error;
222                 }
223                 
224                 XDebugResponse() {
225                         fTransactionID = -1;
226                         fCommand = "";
227                         fStatus = "";
228                         fReason = "";                   
229                         fName= "";
230                 }
231         }
232         
233         private XDebugConnection fConnection;
234         private XDebugResponse lastResponse; 
235
236         public ResponseListener(XDebugConnection connection) {
237                 super("XDebug Event Dispatch");
238                 setSystem(true);
239                 fConnection = connection;
240                 lastResponse = new XDebugResponse();
241                 fResponseList = new ResponseList();
242         }
243                 
244         private void checkResponse(XDebugResponse response) {
245                 Node node = response.getParentNode();
246                 if (node.hasChildNodes()) {
247                         Node child = node.getFirstChild();
248                         if (child.getNodeName().equals("error")) {
249                                 int code = Integer.parseInt(PHPDebugUtils.getAttributeValue(child, "code"));
250                                 String text=(child.getFirstChild()).getNodeValue();
251                                 XDebugCorePlugin.log(IStatus.ERROR," ERROR "+code+": "+text);
252                                 lastResponse.setError(true);
253                                 return;
254                         }
255                 }
256                 lastResponse.setError(false);
257                 if (response.getStatus().equals("stopping")) {
258                         this.cancel();
259                         fireEvent(IPHPDebugEvent.STOPPED);
260                 } else if (response.getStatus().equals("break") && response.getReason().equals("ok")){ 
261                         if (response.getCommand().equals("run")) {
262                                 fireEvent(IPHPDebugEvent.BREAKPOINT_HIT, null);
263                         } else if (response.getCommand().equals("step_into")) {
264                                 fireEvent(IPHPDebugEvent.STEP_END);
265                         } else if (response.getCommand().equals("step_over")) {
266                                 fireEvent(IPHPDebugEvent.STEP_END);
267                         } else if (response.getCommand().equals("step_out")) {
268                                 fireEvent(IPHPDebugEvent.STEP_END);
269                         } 
270                 } 
271         }
272         
273         protected void fireEvent(int detail) {
274                 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
275                 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
276         }
277         
278         protected void fireEvent(int detail, Object data) {
279                 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
280                 event.setData(data);
281                 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
282         }
283         
284         /* (non-Javadoc)
285          * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
286          */
287         protected IStatus run(IProgressMonitor monitor) {
288                 String InputXML = "";
289                 while (!fConnection.isClosed() && (InputXML != null)) {
290                         if (!monitor.isCanceled()) {
291                                 try {
292                                 if(!fConnection.isClosed()) {
293                                         InputXML = fConnection.readData();
294                                 }
295                                 } catch (Exception e) {
296                                         ; //
297                                 }
298                                 if (InputXML != null) {
299                                         XDebugCorePlugin.log(IStatus.INFO, InputXML);
300                                         lastResponse.setParentNode(InputXML);
301                                         if (lastResponse.getName() == "response") {
302                                                 addResponse(lastResponse, lastResponse.getTransactionID());
303                                                 checkResponse(lastResponse);
304                                         }
305                                 }
306                         }
307                 }
308                 return Status.OK_STATUS;
309         }
310         private ResponseList fResponseList;
311         
312         protected void addResponse(XDebugResponse response, int id) {
313                 fResponseList.add(response, id);
314         }
315         
316         public XDebugResponse getResponse(int id) {
317                 return fResponseList.get(id);
318         }
319 }