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 XDebugResponse(String XMLInput) {
58 setParentNode(XMLInput);
61 /*public*/private synchronized void setParentNode(String xmlInput) {
62 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
63 DocumentBuilder builder = null;
67 builder = factory.newDocumentBuilder();
68 } catch (ParserConfigurationException e) {
71 ByteArrayInputStream InputXMLStream = new ByteArrayInputStream(xmlInput.getBytes());
73 doc = builder.parse(InputXMLStream);
74 } catch (SAXException e) {
76 } catch (IOException e) {
80 parentNode = doc.getFirstChild();
82 String responseType = parentNode.getNodeName();
83 if (responseType == TYPE_INIT) {
85 parseInit(parentNode);
86 } else if (responseType == TYPE_RESPONSE) {
87 fName = TYPE_RESPONSE;
88 parseResponse(parentNode);
89 } else if (responseType == TYPE_STREAM) {
97 private void parseInit(Node parentNode) {
98 fIdeKey = getAttributeValue("idekey");
100 /*int startIdx = initString.indexOf("idekey=\"");
104 int endIdx=initString.indexOf('"',startIdx);
107 fSessionID = initString.substring(startIdx,endIdx);*/
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);
127 fStatus = getAttributeValue("status");
128 fReason = getAttributeValue("reason");
130 if( fCommand.compareTo("eval") == 0 ) {
132 Node property = parentNode.getFirstChild();
134 NamedNodeMap listAttribute = property.getAttributes();
135 Node attribute = listAttribute.getNamedItem("type");
136 if (attribute !=null) {
137 fType = attribute.getNodeValue();
140 Node attribute1 = listAttribute.getNamedItem("address");
141 if (attribute1 !=null) {
142 fAddress = attribute1.getNodeValue();
145 Node firstChild1 = (Node) property.getFirstChild();
147 if( firstChild1 != null ) {
148 fValue = firstChild1.getNodeValue();
152 } catch (Exception e) {
153 // TODO: handle exception
157 CDATASection firstChild = (CDATASection) parentNode.getFirstChild();
159 if( firstChild != null ) {
160 fValue = parentNode.getFirstChild().getNodeValue();
162 } catch (Exception e) {
168 private void parseStream() {
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();
184 public synchronized Node getParentNode(){
188 /*public*/private synchronized String getCommand() {
191 /*public*/private synchronized String getName() {
195 public synchronized String getValue() {
199 public synchronized String getReason() {
203 public synchronized String getStatus() {
207 public synchronized int getTransactionID() {
208 return fTransactionID;
211 public boolean isError() {
217 private XDebugConnection fConnection;
218 private ResponseList fResponseList;
220 public ResponseListener(XDebugConnection connection) {
221 super("XDebug Event Dispatch");
223 fConnection = connection;
224 fResponseList = new ResponseList();
227 private void checkResponse(XDebugResponse response) {
228 if (response.getStatus().equals("stopping") || response.getStatus().equals("stopped")) {
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);
244 private void fireEvent(int detail, Object data) {
245 DebugEvent event = new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, detail);
247 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event});
251 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
253 protected IStatus run(IProgressMonitor monitor) {
254 String InputXML = "";
255 while (!fConnection.isClosed()) {
256 if (!monitor.isCanceled()) {
258 InputXML = fConnection.readData();
259 } catch (Exception e) {
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);
272 return Status.OK_STATUS;
275 public XDebugResponse getResponse(int id) {
276 return fResponseList.get(id);