d1ea8f85607b94ac64b861c507be139ece0d2141
[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 XDebugResponse(String XMLInput) {
53                         fTransactionID = -1;
54                         fCommand = "";
55                         fStatus = "";
56                         fReason = "";                   
57                         fName= "";
58                         setParentNode(XMLInput);
59                 }
60         
61                 /*public*/private synchronized void setParentNode(String xmlInput) {
62                         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
63                         DocumentBuilder builder = null;
64                         Document doc = null;
65                         
66                         try {
67                                 builder = factory.newDocumentBuilder();
68                         } catch (ParserConfigurationException e) {
69                                 e.printStackTrace();
70                         }
71                         ByteArrayInputStream InputXMLStream = new ByteArrayInputStream(xmlInput.getBytes());
72                         try {
73                                 doc = builder.parse(InputXMLStream);
74                         } catch (SAXException e) {
75                                 e.printStackTrace();
76                         } catch (IOException e) {
77                                 e.printStackTrace();
78                         }
79         
80                         parentNode = doc.getFirstChild();
81                         
82                         String responseType = parentNode.getNodeName();
83                         if (responseType == TYPE_INIT) {
84                                 fName = TYPE_INIT;
85                                 parseInit(parentNode);
86                         } else if (responseType == TYPE_RESPONSE) {
87                                 fName = TYPE_RESPONSE;
88                                 parseResponse(parentNode);
89                         } else if (responseType == TYPE_STREAM) {
90                                 fName = TYPE_STREAM;
91                                 parseStream();
92                         } else {
93                                 fName = null;
94                         }
95                 }
96                 
97                 private void parseInit(Node parentNode) {
98                         fIdeKey = getAttributeValue("idekey");
99                         
100                         /*int startIdx = initString.indexOf("idekey=\"");
101                         if (startIdx == -1)
102                                 return;
103                         startIdx += 8;
104                         int endIdx=initString.indexOf('"',startIdx);
105                         if (endIdx==-1)
106                                 return;
107                         fSessionID = initString.substring(startIdx,endIdx);*/
108                 }
109                 
110                 private void parseResponse(Node parentNode) {
111                         String idStr = getAttributeValue("transaction_id");
112                         if (!"".equals(idStr))
113                                 fTransactionID = Integer.parseInt(idStr);
114                         fCommand = getAttributeValue("command");
115                         if (parentNode.hasChildNodes()) {
116                                 Node child = parentNode.getFirstChild();
117                                 if (child.getNodeName().equals("error")) {
118                                         int code = Integer.parseInt(PHPDebugUtils.getAttributeValue(child, "code"));
119                                         String text = (child.getFirstChild()).getNodeValue();
120                                         XDebugCorePlugin.log(IStatus.ERROR," ERROR "+code+": "+text);
121                                         fError = true;
122                                         return;
123                                 }
124                         }
125                         fError = false;
126                         
127                         fStatus = getAttributeValue("status");
128                         fReason = getAttributeValue("reason");
129         
130                         if( fCommand.compareTo("eval") == 0 ) {
131                                 try {
132                                         Node property = parentNode.getFirstChild();
133         
134                                         NamedNodeMap listAttribute = property.getAttributes();
135                                         Node attribute = listAttribute.getNamedItem("type");
136                                         if (attribute !=null) {
137                                                 fType = attribute.getNodeValue();
138                                         }
139         
140                                         Node attribute1 = listAttribute.getNamedItem("address");
141                                         if (attribute1 !=null) {
142                                                 fAddress = attribute1.getNodeValue();
143                                         }
144                                         
145                                         Node firstChild1 = (Node) property.getFirstChild();
146                                         
147                                         if( firstChild1 != null ) {
148                                                 fValue = firstChild1.getNodeValue();
149                                         } else {
150                                                 fValue = "";
151                                         }
152                                 } catch (Exception e) {
153                                         // TODO: handle exception
154                                 }
155                         } else {
156                                 try {
157                                         CDATASection firstChild = (CDATASection) parentNode.getFirstChild();
158         
159                                         if( firstChild != null ) {
160                                                 fValue = parentNode.getFirstChild().getNodeValue();
161                                         }
162                                 } catch (Exception e) {
163                                 }
164                         }
165                         
166                 }
167                 
168                 private void parseStream() {
169                         
170                 }
171                 
172                 
173                 public String getAttributeValue (String AttributeName) {
174                         String strValue = "";
175                         if (parentNode.hasAttributes()) {
176                                 NamedNodeMap listAttribute = parentNode.getAttributes();
177                                 Node attribute = listAttribute.getNamedItem(AttributeName);
178                                 if (attribute !=null)
179                                         strValue = attribute.getNodeValue();
180                         }
181                         return strValue;
182                 }
183                 
184                 public synchronized Node getParentNode(){
185                         return parentNode;
186                 }
187                 
188                 /*public*/private  synchronized String getCommand() {
189                         return fCommand;
190                 }
191                 /*public*/private synchronized String getName() {
192                         return fName;
193                 }
194                 
195                 public synchronized String getValue() {
196                         return fValue;
197                 }
198         
199                 public synchronized String getReason() {
200                         return fReason;
201                 }
202         
203                 public synchronized String getStatus() {
204                         return fStatus;
205                 }
206         
207                 public synchronized int getTransactionID() {
208                         return fTransactionID;
209                 }
210                 
211                 public boolean isError() {
212                         return fError;
213                 }
214         }
215         
216         
217         private XDebugConnection fConnection;
218         private ResponseList fResponseList;
219         
220         public ResponseListener(XDebugConnection connection) {
221                 super("XDebug Event Dispatch");
222                 setSystem(true);
223                 fConnection = connection;
224                 fResponseList = new ResponseList();
225         }
226                 
227         private void checkResponse(XDebugResponse response) {
228                 if (response.getStatus().equals("stopping") || response.getStatus().equals("stopped")) {
229                         this.cancel();
230                         fireEvent(IPHPDebugEvent.STOPPED, null);
231                 } else if (response.getStatus().equals("break") && response.getReason().equals("ok")){ 
232                         if (response.getCommand().equals("run")) {
233                                 fireEvent(IPHPDebugEvent.BREAKPOINT_HIT, null);
234                         } else if (response.getCommand().equals("step_into")) {
235                                 fireEvent(IPHPDebugEvent.STEP_END, null);
236                         } else if (response.getCommand().equals("step_over")) {
237                                 fireEvent(IPHPDebugEvent.STEP_END, null);
238                         } else if (response.getCommand().equals("step_out")) {
239                                 fireEvent(IPHPDebugEvent.STEP_END, null);
240                         } 
241                 } 
242         }
243         
244         private void fireEvent(int detail, Object data) {
245                 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
246                 event.setData(data);
247                 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
248         }
249         
250         /* (non-Javadoc)
251          * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
252          */
253         protected IStatus run(IProgressMonitor monitor) {
254                 String InputXML = "";
255                 while (!fConnection.isClosed()) {
256                         if (!monitor.isCanceled()) {
257                                 try {
258                                         InputXML = fConnection.readData();
259                                 } catch (Exception e) {
260                                         ; //
261                                 }
262                                 if (InputXML != null) {
263                                         XDebugCorePlugin.log(IStatus.INFO, InputXML);
264                                         XDebugResponse response = new XDebugResponse(InputXML);
265                                         if (response.getName() == "response") {
266                                                 fResponseList.add(response);
267                                                 checkResponse(response);
268                                         }
269                                 }
270                         }
271                 }
272                 return Status.OK_STATUS;
273         }
274
275         public XDebugResponse getResponse(int id) {
276                 return fResponseList.get(id);
277         }
278 }