blob: 94c6c68f1d1ffbef5480f154e13636d2c25da801 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.e4.languages.javascript.jsdi.rhino;
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.JSONConstants;
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.StackFrameReference;
import org.eclipse.e4.languages.javascript.jsdi.ThreadReference;
/**
* Rhino implementation of {@link ThreadReference}
*
* @since 1.0
*/
public class ThreadReferenceImpl extends MirrorImpl implements ThreadReference {
private Number threadId;
private List frames;
private int status = THREAD_STATUS_RUNNING;
private boolean suspended;
private boolean atBreakpoint = false;
private String name;
private String step;
/**
* Constructor
*
* @param vm
* @param jsonThread
*/
public ThreadReferenceImpl(VirtualMachineImpl vm, Map jsonThread) {
super(vm);
this.threadId = (Number) jsonThread.get(JSONConstants.THREAD_ID);
this.name = (String) jsonThread.get(JSONConstants.NAME);
if (this.name == null) {
// TODO NLS this
this.name = "Rhino - " + threadId; //$NON-NLS-1$
}
this.suspended = JSONConstants.SUSPENDED.equals(jsonThread
.get(JSONConstants.STATE));
}
/**
* Constructor
*
* @param vm
* @param threadId
*/
private ThreadReferenceImpl(VirtualMachineImpl vm, Long threadId) {
super(vm);
this.threadId = threadId;
// TODO NLS this
this.name = "Rhino - " + threadId; //$NON-NLS-1$
this.status = THREAD_STATUS_ZOMBIE;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.e4.languages.javascript.jsdi.ThreadReference#frameCount()
*/
public synchronized int frameCount() {
frames();
return frames.size();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.e4.languages.javascript.jsdi.ThreadReference#frame(int)
*/
public synchronized StackFrameReference frame(int index) {
frames();
return (StackFrameReference) frames.get(index);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.e4.languages.javascript.jsdi.ThreadReference#frames()
*/
public synchronized List frames() {
if (!suspended || status == THREAD_STATUS_ZOMBIE)
return Collections.EMPTY_LIST;
if (frames != null)
return frames;
Request request = new Request(JSONConstants.FRAMES);
request.getArguments().put(JSONConstants.THREAD_ID, threadId);
try {
Response response = vm.sendRequest(request, 30000);
List frameIds = (List) response.getBody().get(JSONConstants.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());
StackFrameReferenceImpl frame = createStackFrame(frameId);
frames.add(frame);
}
} catch (DisconnectException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return frames;
}
/**
* Sends a request to make a new {@link StackFrameReference} in the current debugger.
* Returns a new {@link StackFrameReference} on success, <code>null</code> on failure
*
* @param frameId
* @return a new {@link StackFrameReference} or <code>null</code>
*/
private StackFrameReferenceImpl createStackFrame(Long frameId) {
Request request = new Request(JSONConstants.FRAME);
request.getArguments().put(JSONConstants.THREAD_ID, threadId);
request.getArguments().put(JSONConstants.FRAME_ID, frameId);
try {
Response response = vm.sendRequest(request, 30000);
Map jsonFrame = (Map) response.getBody().get(JSONConstants.FRAME);
return new StackFrameReferenceImpl(vm, jsonFrame);
} catch (DisconnectException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.e4.languages.javascript.jsdi.ThreadReference#isAtBreakpoint()
*/
public synchronized boolean isAtBreakpoint() {
return suspended && atBreakpoint;
}
/**
* Marks the current thread reference as suspended
*
* @param atBreakpoint
*/
public synchronized void markSuspended(boolean atBreakpoint) {
this.suspended = true;
this.atBreakpoint = atBreakpoint;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.e4.languages.javascript.jsdi.ThreadReference#isSuspended()
*/
public synchronized boolean isSuspended() {
return suspended;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.e4.languages.javascript.jsdi.ThreadReference#name()
*/
public String name() {
return name;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.e4.languages.javascript.jsdi.ThreadReference#resume()
*/
public synchronized void resume() {
if (status == THREAD_STATUS_ZOMBIE) {
return;
}
Request request = new Request(JSONConstants.CONTINUE);
request.getArguments().put(JSONConstants.THREAD_ID, threadId);
if (step != null) {
request.getArguments().put(JSONConstants.STEP, step);
}
try {
Response response = vm.sendRequest(request, 30000);
if (response.isSuccess()) {
step = null;
frames = null;
suspended = false;
atBreakpoint = false;
}
} catch (DisconnectException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.e4.languages.javascript.jsdi.ThreadReference#suspend()
*/
public void suspend() {
if (status == THREAD_STATUS_ZOMBIE) {
return;
}
Request request = new Request(JSONConstants.SUSPEND);
request.getArguments().put(JSONConstants.THREAD_ID, threadId);
try {
vm.sendRequest(request, 30000);
} catch (DisconnectException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.e4.languages.javascript.jsdi.ThreadReference#interrupt()
*/
public void interrupt() {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.e4.languages.javascript.jsdi.ThreadReference#status()
*/
public synchronized int status() {
return status;
}
/**
* Returns the step type
*
* @return the step type
* @see JSONConstants#STEP_IN
* @see JSONConstants#STEP_NEXT
* @see JSONConstants#STEP_OUT
*/
public synchronized String getStep() {
return step;
}
/**
* Sets the current step type
*
* @param step
* @see JSONConstants#STEP_IN
* @see JSONConstants#STEP_NEXT
* @see JSONConstants#STEP_OUT
*/
public synchronized void setStep(String step) {
this.step = step;
}
/**
* Creates a new thread that is in the zombie state - i.e. not running and
* not initialized
*
* @param vm
* @param threadId
* @return a new {@link ThreadReference}
*/
public static ThreadReferenceImpl zombie(VirtualMachineImpl vm,
Long threadId) {
return new ThreadReferenceImpl(vm, threadId);
}
}