/* * Created on 23.11.2004 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package net.sourceforge.phpeclipse.xdebug.php.model; import java.net.MalformedURLException; import java.net.URL; import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils; import net.sourceforge.phpeclipse.xdebug.core.xdebug.ResponseListener.XDebugResponse; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IDebugEventSetListener; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Axel * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class XDebugThread extends XDebugElement implements IThread, IDebugEventSetListener { private XDebugStackFrame[] fStackFrames; private IBreakpoint[] fBreakpoints; /* Whether this thread is stepping */ private boolean fStepping = false; private boolean fTerminated = false; private int fStepCount = 0; private int fCurrentStepCount = 0; /** * Constructs a new thread for the given target * * @param target VM */ public XDebugThread(XDebugTarget target) { super(target); DebugPlugin.getDefault().addDebugEventListener(this); fStackFrames = null; } public void incrementStepCounter() { fStepCount++; } public IStackFrame[] getStackFrames() throws DebugException { if (!isSuspended()) { return new IStackFrame[0]; } if (fStepCount > fCurrentStepCount) { XDebugResponse dr = ((XDebugTarget) getDebugTarget()).getStackFrames(); XDebugStackFrame[] newStackFrames = _getStackFrames(dr); /*if (fStackFrames != null) { if (newStackFrames.length >= fStackFrames.length) { int delta = newStackFrames.length - fStackFrames.length + 1; for (int i = fStackFrames.length - 1; i >= 0; i--) { if (fStackFrames[i].equals(newStackFrames[newStackFrames.length - delta])) { int b = 2; b++; //((XDebugStackFrame) newStackFrames[newStackFrames.length - delta]).evaluateChange((XDebugStackFrame) fStackFrames[i]); } else if (fStackFrames[i].isSameStackFrame(newStackFrames[newStackFrames.length - delta])) { int b = 2; b++; //((XDebugStackFrame) newStackFrames[newStackFrames.length - delta]).evaluateChange((XDebugStackFrame) fStackFrames[i]); } delta ++; } } else { fStackFrames = newStackFrames; } } else { fStackFrames = newStackFrames; }*/ fCurrentStepCount++; fStackFrames = newStackFrames; } return fStackFrames; } private XDebugStackFrame[] _getStackFrames(XDebugResponse lastResponse) { if (lastResponse.isError()) { return new XDebugStackFrame[0]; } Node response = lastResponse.getParentNode(); NodeList frames = response.getChildNodes(); XDebugStackFrame[] theFrames = new XDebugStackFrame[frames.getLength()]; for (int i = 0; i < frames.getLength(); i++) { Node stackNode = frames.item(i); XDebugStackFrame frame = new XDebugStackFrame(this/*fThread*/, i); String level =PHPDebugUtils.getAttributeValue(stackNode,"level"); if (!"".equals(level)) frame.setLevel(Integer.parseInt(level)); frame.setType(PHPDebugUtils.getAttributeValue(stackNode,"type")); String fileName=PHPDebugUtils.unescapeString(PHPDebugUtils.getAttributeValue(stackNode,"filename")); String lineNo=PHPDebugUtils.getAttributeValue(stackNode,"lineno"); if (!"".equals(lineNo)) frame.setLineNumber(Integer.parseInt(lineNo)); frame.setWhere(PHPDebugUtils.getAttributeValue(stackNode,"where")); try { frame.setFullName(new URL(fileName)); } catch (MalformedURLException e) { e.printStackTrace(); } frame.incrementStepCounter(); theFrames[i] = frame; } return theFrames; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IThread#hasStackFrames() */ public boolean hasStackFrames() throws DebugException { return isSuspended(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IThread#getPriority() */ public int getPriority() throws DebugException { return 0; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IThread#getTopStackFrame() */ public IStackFrame getTopStackFrame() throws DebugException { IStackFrame[] frames = getStackFrames(); if (frames.length > 0) { return frames[0]; } return null; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IThread#getName() */ public String getName() throws DebugException { return "Thread[1]"; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IThread#getBreakpoints() */ public IBreakpoint[] getBreakpoints() { if (fBreakpoints == null) { return new IBreakpoint[0]; } return fBreakpoints; } /** * Sets the breakpoints this thread is suspended at, or null * if none. * * @param breakpoints the breakpoints this thread is suspended at, or null * if none */ protected void setBreakpoints(IBreakpoint[] breakpoints) { fBreakpoints = breakpoints; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#canResume() */ public boolean canResume() { return isSuspended(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend() */ public boolean canSuspend() { return !isTerminated() && !isSuspended(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended() */ public boolean isSuspended() { // return fTarget.isSuspended(); return getDebugTarget().isSuspended(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#resume() */ public void resume() throws DebugException { fBreakpoints=null; getDebugTarget().resume(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.ISuspendResume#suspend() */ public void suspend() throws DebugException { getDebugTarget().suspend(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IStep#canStepInto() */ public boolean canStepInto() { return isSuspended(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IStep#canStepOver() */ public boolean canStepOver() { return isSuspended(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IStep#canStepReturn() */ public boolean canStepReturn() { if (fStackFrames != null) { return (fStackFrames.length > 1); } else { return false; } } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IStep#isStepping() */ public boolean isStepping() { return fStepping; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IStep#stepInto() */ public void stepInto() throws DebugException { fBreakpoints=null; ((XDebugTarget) getDebugTarget()).step_into(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IStep#stepOver() */ public void stepOver() throws DebugException { fBreakpoints=null; ((XDebugTarget) getDebugTarget()).step_over(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IStep#stepReturn() */ public void stepReturn() throws DebugException { fBreakpoints=null; ((XDebugTarget) getDebugTarget()).step_out(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.ITerminate#canTerminate() */ public boolean canTerminate() { return !isTerminated(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.ITerminate#isTerminated() */ public boolean isTerminated() { return fTerminated; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.ITerminate#terminate() */ public void terminate() throws DebugException { ((XDebugTarget) getDebugTarget()).getDebugConnection().stop(); fTerminated = true; } public void terminated() throws DebugException { fTerminated = true; } /** * Sets whether this thread is stepping * * @param stepping whether stepping */ protected void setStepping(boolean stepping) { fStepping = stepping; } public void handleDebugEvents(DebugEvent[] events) { DebugEvent de = events[0]; System.out.println(de.toString()); } public void removeEventListeners() { DebugPlugin.getDefault().removeDebugEventListener(this); } /** * Fires a debug event * * @param event the event to be fired */ protected void fireEvent(DebugEvent event) { DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event}); } /** * Fires a CREATE event for this element. */ public void fireCreationEvent() { fireEvent(new DebugEvent(this, DebugEvent.CREATE)); } /** * Fires a RESUME event for this element with * the given detail. * * @param detail event detail code */ public void fireResumeEvent(int detail) { fireEvent(new DebugEvent(this, DebugEvent.RESUME, detail)); } /** * Fires a SUSPEND event for this element with * the given detail. * * @param detail event detail code */ public void fireSuspendEvent(int detail) { fireEvent(new DebugEvent(this, DebugEvent.SUSPEND, detail)); } /** * Fires a TERMINATE event for this element. */ protected void fireTerminateEvent() { fireEvent(new DebugEvent(this, DebugEvent.TERMINATE)); } }