1 package net.sourceforge.phpeclipse.xdebug.core.xdebug;
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
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;
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;
27 * Listens to events from the XDebug and fires corresponding
31 public class ResponseListener extends Job {
32 public class XDebugResponse {
33 final public static String TYPE_INIT = "init";
35 final public static String TYPE_RESPONSE = "response";
37 final public static String TYPE_STREAM = "stream";
39 private Node parentNode;
40 private int fTransactionID = -1;
41 private String fCommand = "";
42 private String fStatus;
43 private String fReason;
45 private boolean fError;
47 private String fValue;
49 private String fAddress;
50 private String fIdeKey;
52 public synchronized void setParentNode(String xmlInput) {
53 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
54 DocumentBuilder builder = null;
58 builder = factory.newDocumentBuilder();
59 } catch (ParserConfigurationException e) {
62 ByteArrayInputStream InputXMLStream = new ByteArrayInputStream(xmlInput.getBytes());
64 doc = builder.parse(InputXMLStream);
65 } catch (SAXException e) {
67 } catch (IOException e) {
71 parentNode = doc.getFirstChild();
73 String responseType = parentNode.getNodeName();
74 if (responseType == TYPE_INIT) {
76 parseInit(parentNode);
77 } else if (responseType == TYPE_RESPONSE) {
78 fName = TYPE_RESPONSE;
79 parseResponse(parentNode);
80 } else if (responseType == TYPE_STREAM) {
88 private void parseInit(Node parentNode) {
89 fIdeKey = getAttributeValue("idekey");
91 /*int startIdx = initString.indexOf("idekey=\"");
95 int endIdx=initString.indexOf('"',startIdx);
98 fSessionID = initString.substring(startIdx,endIdx);*/
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);
118 fStatus = getAttributeValue("status");
119 fReason = getAttributeValue("reason");
121 if( fCommand.compareTo("eval") == 0 ) {
123 Node property = parentNode.getFirstChild();
125 NamedNodeMap listAttribute = property.getAttributes();
126 Node attribute = listAttribute.getNamedItem("type");
127 if (attribute !=null) {
128 fType = attribute.getNodeValue();
131 Node attribute1 = listAttribute.getNamedItem("address");
132 if (attribute1 !=null) {
133 fAddress = attribute1.getNodeValue();
136 Node firstChild1 = (Node) property.getFirstChild();
138 if( firstChild1 != null ) {
139 fValue = firstChild1.getNodeValue();
141 } catch (Exception e) {
142 // TODO: handle exception
146 CDATASection firstChild = (CDATASection) parentNode.getFirstChild();
148 if( firstChild != null ) {
149 fValue = parentNode.getFirstChild().getNodeValue();
151 } catch (Exception e) {
157 private void parseStream() {
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();
173 public synchronized Node getParentNode(){
177 public synchronized String getIdeKey(){
181 public synchronized String getCommand() {
184 public synchronized String getName() {
188 public synchronized String getValue() {
192 public synchronized String getType() {
196 public synchronized String getAddress() {
200 public XDebugResponse(String XMLInput) {
201 setParentNode(XMLInput);
204 public synchronized String getReason() {
208 public synchronized String getStatus() {
212 public synchronized int getTransactionID() {
213 return fTransactionID;
216 public boolean isError() {
220 public void setError(boolean error) {
233 private XDebugConnection fConnection;
234 private XDebugResponse lastResponse;
236 public ResponseListener(XDebugConnection connection) {
237 super("XDebug Event Dispatch");
239 fConnection = connection;
240 lastResponse = new XDebugResponse();
241 fResponseList = new ResponseList();
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);
256 lastResponse.setError(false);
257 if (response.getStatus().equals("stopping") || response.getStatus().equals("stopped")) {
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);
273 protected void fireEvent(int detail) {
274 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
275 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
278 protected void fireEvent(int detail, Object data) {
279 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
281 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
285 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
287 protected IStatus run(IProgressMonitor monitor) {
288 String InputXML = "";
289 while (!fConnection.isClosed() && (InputXML != null)) {
290 if (!monitor.isCanceled()) {
292 if(!fConnection.isClosed()) {
293 InputXML = fConnection.readData();
295 } catch (Exception e) {
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);
308 return Status.OK_STATUS;
310 private ResponseList fResponseList;
312 protected void addResponse(XDebugResponse response, int id) {
313 fResponseList.add(response, id);
316 public XDebugResponse getResponse(int id) {
317 return fResponseList.get(id);