blob: 144d4ef17f1107ca9e08b32d83f9ecdd7cc4e07e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ant.internal.ui.debug.model;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IVariable;
/**
* An Ant build thread.
*/
public class AntThread extends AntDebugElement implements IThread {
/**
* Breakpoints this thread is suspended at or <code>null</code>
* if none.
*/
private IBreakpoint[] fBreakpoints;
/**
* The stackframes associated with this thread
*/
private List fFrames= new ArrayList(1);
/**
* Whether this thread is stepping
*/
private boolean fStepping = false;
/**
* The properties associated with this thread
*/
private List fProperties;
private boolean fRefreshProperties= true;
/**
* Constructs a new thread for the given target
*
* @param target the Ant Build
*/
public AntThread(AntDebugTarget target) {
super(target);
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IThread#getStackFrames()
*/
public synchronized IStackFrame[] getStackFrames() throws DebugException {
if (isSuspended()) {
if (fFrames.size() == 0) {
getStackFrames0();
}
}
return (IStackFrame[]) fFrames.toArray(new IStackFrame[fFrames.size()]);
}
/**
* Returns the current stack frames in the thread
* possibly waiting until the frames are populating
*
* @return the current stack frames in the thread
* @throws DebugException if unable to perform the request
*/
private void getStackFrames0() {
fTarget.getStackFrames();
if (fFrames.size() > 0) {
//frames set..no need to wait
return;
}
try {
wait();
} catch (InterruptedException e) {
}
}
/* (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 != null && frames.length > 0) {
return frames[0];
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IThread#getName()
*/
public String getName() {
return "Thread [Ant Build]"; //$NON-NLS-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 <code>null</code>
* if none.
*
* @param breakpoints the breakpoints this thread is suspended at, or <code>null</code>
* 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 !isSuspended();
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
*/
public boolean isSuspended() {
return getDebugTarget().isSuspended();
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#resume()
*/
public synchronized void resume() throws DebugException {
aboutToResume(DebugEvent.CLIENT_REQUEST, false);
getDebugTarget().resume();
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#suspend()
*/
public synchronized 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() {
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 synchronized void stepInto() throws DebugException {
aboutToResume(DebugEvent.STEP_INTO, true);
((AntDebugTarget)getDebugTarget()).stepInto();
}
private void aboutToResume(int detail, boolean stepping) {
fRefreshProperties= true;
fFrames.clear();
setStepping(stepping);
setBreakpoints(null);
fireResumeEvent(detail);
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#stepOver()
*/
public synchronized void stepOver() throws DebugException {
aboutToResume(DebugEvent.STEP_OVER, true);
((AntDebugTarget)getDebugTarget()).stepOver();
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#stepReturn()
*/
public synchronized void stepReturn() throws DebugException {
}
/* (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 getDebugTarget().isTerminated();
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ITerminate#terminate()
*/
public void terminate() throws DebugException {
fFrames.clear();
getDebugTarget().terminate();
}
/**
* Sets whether this thread is stepping
*
* @param stepping whether stepping
*/
protected void setStepping(boolean stepping) {
fStepping = stepping;
}
public synchronized void buildStack(String data) {
String[] strings= data.split(DebugMessageIds.MESSAGE_DELIMITER);
//0 STACK message
//1 targetName
//2 taskName
//3 filePath
//4 lineNumber
//5 ...
fFrames.clear();
String name;
String filePath;
int lineNumber;
AntStackFrame frame;
int stackFrameId= 0;
for (int i = 1; i < strings.length; i++) {
name= strings[i] + ": " + strings[++i]; //$NON-NLS-1$
filePath= strings[++i];
lineNumber= Integer.parseInt(strings[++i]);
frame= new AntStackFrame(this, stackFrameId++, name, filePath, lineNumber);
fFrames.add(frame);
}
//wake up the call from getStackFrames
notifyAll();
}
public synchronized void newProperties(String data) {
try {
String[] datum= data.split(DebugMessageIds.MESSAGE_DELIMITER);
if (fProperties == null) {
fProperties= new ArrayList(datum.length);
}
//0 PROPERTIES message
//1 propertyName length
//2 propertyName
//3 propertyValue length
//3 propertyValue
//4 ...
if (datum.length > 1) { //new properties
String propertyName;
String propertyValue;
AntProperty property;
int propertyNameLength;
int propertyValueLength;
for (int i = 1; i < datum.length; i++) {
propertyNameLength= Integer.parseInt(datum[i]);
propertyName= datum[++i];
while (propertyName.length() != propertyNameLength) {
propertyName+= DebugMessageIds.MESSAGE_DELIMITER + datum[++i];
}
propertyValueLength= Integer.parseInt(datum[++i]);
if (propertyValueLength == 0 && i + 1 == datum.length) {
//bug 81299
propertyValue= ""; //$NON-NLS-1$
} else {
propertyValue= datum[++i];
}
while (propertyValue.length() != propertyValueLength) {
propertyValue+= DebugMessageIds.MESSAGE_DELIMITER + datum[++i];
}
property= new AntProperty((AntDebugTarget) getDebugTarget(), propertyName, propertyValue);
fProperties.add(property);
}
}
} finally {
fRefreshProperties= false;
//wake up the call from getVariables
notifyAll();
}
}
protected synchronized IVariable[] getVariables() {
if (fRefreshProperties) {
fTarget.getProperties();
if (fRefreshProperties) {
//properties have not been set; need to wait
try {
wait();
} catch (InterruptedException ie) {
}
}
}
return (IVariable[])fProperties.toArray(new IVariable[fProperties.size()]);
}
}