blob: c24975c469136cde1f39bdc5e0d34bd9ce9ea84d [file] [log] [blame]
package org.eclipse.e4.languages.javascript.rhino.jsdi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.e4.languages.javascript.debug.connect.DisconnectException;
import org.eclipse.e4.languages.javascript.debug.connect.Request;
import org.eclipse.e4.languages.javascript.debug.connect.Response;
import org.eclipse.e4.languages.javascript.debug.connect.TimeoutException;
import org.eclipse.e4.languages.javascript.jsdi.StackFrame;
import org.eclipse.e4.languages.javascript.jsdi.ThreadReference;
public class ThreadReferenceImpl extends MirrorImpl implements ThreadReference {
private Number threadId;
private List frames = new ArrayList();
private int status = THREAD_STATUS_RUNNING;
private boolean suspended;
private boolean atBreakpoint = false;
private String name;
private String step;
public ThreadReferenceImpl(VirtualMachineImpl vm, Map jsonThread) {
super(vm);
this.threadId = (Number) jsonThread.get("threadId");
this.name = (String) jsonThread.get("name");
if (this.name == null)
this.name = "Rhino thread - " + threadId;
this.suspended = "suspended".equals(jsonThread.get("state"));
}
private ThreadReferenceImpl(VirtualMachineImpl vm, Long threadId) {
super(vm);
this.threadId = threadId;
this.name = "Rhino thread - " + threadId;
this.status = THREAD_STATUS_ZOMBIE;
this.frames = Collections.EMPTY_LIST;
}
public synchronized int frameCount() {
frames();
return frames.size();
}
public synchronized StackFrame frame(int index) {
frames();
return (StackFrame) frames.get(index);
}
public synchronized List frames() {
if (status == THREAD_STATUS_ZOMBIE)
return frames;
if (!suspended)
throw new IllegalStateException("not suspended");
if (frames != null)
return frames;
Request request = new Request("frames");
request.getArguments().put("threadId", threadId);
try {
Response response = vm.sendRequest(request, 30000);
List frameIds = (List) response.getBody().get("frames");
if (frameIds.isEmpty()) {
frames = Collections.EMPTY_LIST;
return frames;
}
frames = new ArrayList();
for (Iterator iterator = frameIds.iterator(); iterator.hasNext();) {
Long frameId = new Long(((Number) iterator.next()).longValue());
StackFrameImpl frame = createStackFrame(frameId);
frames.add(frame);
}
} catch (DisconnectException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return frames;
}
private StackFrameImpl createStackFrame(Long frameId) {
Request request = new Request("frame");
request.getArguments().put("threadId", threadId);
request.getArguments().put("frameId", frameId);
try {
Response response = vm.sendRequest(request, 30000);
Map jsonFrame = (Map) response.getBody().get("frame");
return new StackFrameImpl(vm, jsonFrame);
} catch (DisconnectException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return null;
}
public synchronized boolean isAtBreakpoint() {
return suspended && atBreakpoint;
}
public synchronized void markSuspended(boolean atBreakpoint) {
this.suspended = true;
this.atBreakpoint = atBreakpoint;
}
public synchronized boolean isSuspended() {
return suspended;
}
public String name() {
return name;
}
public synchronized void resume() {
if (status == THREAD_STATUS_ZOMBIE) {
return;
}
Request request = new Request("continue");
request.getArguments().put("threadId", threadId);
if (step != null) {
request.getArguments().put("step", step);
}
try {
Response response = vm.sendRequest(request, 30000);
if (response.isSuccess()) {
frames = null;
suspended = false;
atBreakpoint = false;
}
} catch (DisconnectException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
public void suspend() {
if (status == THREAD_STATUS_ZOMBIE) {
return;
}
Request request = new Request("suspend");
request.getArguments().put("threadId", threadId);
try {
vm.sendRequest(request, 30000);
// TODO: really make this work
suspended = true;
} catch (DisconnectException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
public void interrupt() {
throw new UnsupportedOperationException();
}
public synchronized int status() {
return status;
}
public synchronized String getStep() {
return step;
}
public synchronized void setStep(String step) {
this.step = step;
}
public static ThreadReferenceImpl zombie(VirtualMachineImpl vm, Long threadId) {
return new ThreadReferenceImpl(vm, threadId);
}
}