blob: fb9e31aca61f57c6079b006c825cdccae2039c95 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 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.wst.jsdt.debug.internal.rhino.jsdi.event;
import java.util.Iterator;
import java.util.List;
import org.eclipse.wst.jsdt.debug.core.jsdi.Location;
import org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference;
import org.eclipse.wst.jsdt.debug.core.jsdi.event.EventQueue;
import org.eclipse.wst.jsdt.debug.core.jsdi.event.EventSet;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ExceptionRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ScriptLoadRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ThreadEnterRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ThreadExitRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.VMDeathRequest;
import org.eclipse.wst.jsdt.debug.internal.rhino.RhinoDebugPlugin;
import org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.MirrorImpl;
import org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.ScriptReferenceImpl;
import org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.ThreadReferenceImpl;
import org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.VirtualMachineImpl;
import org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.request.BreakpointRequestImpl;
import org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.request.DebuggerStatementRequestImpl;
import org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.request.EventRequestManagerImpl;
import org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.request.StepRequestImpl;
import org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.request.SuspendRequestImpl;
import org.eclipse.wst.jsdt.debug.internal.rhino.transport.EventPacket;
import org.eclipse.wst.jsdt.debug.internal.rhino.transport.JSONConstants;
import org.eclipse.wst.jsdt.debug.transport.exception.DisconnectedException;
import org.eclipse.wst.jsdt.debug.transport.exception.TimeoutException;
/**
* Default implementation of {@link EventQueue}
*
* @since 1.0
*/
public final class EventQueueImpl extends MirrorImpl implements EventQueue {
private VirtualMachineImpl vm;
private EventRequestManagerImpl eventRequestManager;
/**
* Constructor
*
* @param vm
* @param eventRequestManager
*/
public EventQueueImpl(VirtualMachineImpl vm, EventRequestManagerImpl eventRequestManager) {
super(vm);
this.vm = vm;
this.eventRequestManager = eventRequestManager;
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.debug.core.jsdi.event.EventQueue#remove()
*/
public EventSet remove() {
return remove(-1);
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.debug.core.jsdi.event.EventQueue#remove(int)
*/
public EventSet remove(int timeout) {
try {
while (true) {
EventPacket event = vm.receiveEvent(timeout);
String eventName = event.getEvent();
EventSetImpl eventSet = new EventSetImpl(vm);
if (eventName.equals(JSONConstants.SCRIPT)) {
Long threadId = new Long(((Number) event.getBody().get(JSONConstants.THREAD_ID)).longValue());
ThreadReferenceImpl thread = vm.getThread(threadId);
if(thread == null) {
continue;
}
eventSet.setThread(thread);
Long scriptId = new Long(((Number) event.getBody().get(JSONConstants.SCRIPT_ID)).longValue());
ScriptReferenceImpl script = vm.addScript(scriptId);
if(script != null) {
List scriptLoadRequests = eventRequestManager.scriptLoadRequests();
for (Iterator iterator = scriptLoadRequests.iterator(); iterator.hasNext();) {
ScriptLoadRequest request = (ScriptLoadRequest) iterator.next();
if (request.isEnabled()) {
eventSet.add(new ScriptLoadEventImpl(vm, thread, script, request));
}
}
}
if (!eventSet.isEmpty()) {
thread.markSuspended(false);
}
} else if (eventName.equals(JSONConstants.BREAK)) {
Long threadId = new Long(((Number) event.getBody().get(JSONConstants.THREAD_ID)).longValue());
ThreadReferenceImpl thread = vm.getThread(threadId);
if(thread == null) {
continue;
}
eventSet.setThread(thread);
Long scriptId = new Long(((Number) event.getBody().get(JSONConstants.SCRIPT_ID)).longValue());
ScriptReferenceImpl script = vm.getScript(scriptId);
if(script != null) {
int lineNumber = ((Number) event.getBody().get(JSONConstants.LINE)).intValue();
Location location = script.lineLocation(lineNumber);
boolean atBreakpoint = false;
Number breakpointId = (Number) event.getBody().get(JSONConstants.BREAKPOINT);
if (breakpointId != null) {
List breakpointRequests = eventRequestManager.breakpointRequests();
for (Iterator iterator = breakpointRequests.iterator(); iterator.hasNext();) {
BreakpointRequestImpl request = (BreakpointRequestImpl) iterator.next();
ThreadReference requestThread = request.thread();
if (request.isEnabled() && (requestThread == null || thread == requestThread) && breakpointId.longValue() == request.breakpointId().longValue()) {
eventSet.add(new BreakpointEventImpl(vm, thread, location, request));
atBreakpoint = true;
}
}
}
String stepType = (String) event.getBody().get(JSONConstants.STEP);
if (JSONConstants.SUSPENDED.equals(stepType)) {
List suspendRequests = eventRequestManager.suspendRequests();
for (Iterator iterator = suspendRequests.iterator(); iterator.hasNext();) {
SuspendRequestImpl request = (SuspendRequestImpl) iterator.next();
ThreadReference requestThread = request.thread();
if (request.isEnabled() && (requestThread == null || thread == requestThread)) {
eventSet.add(new SuspendEventImpl(vm, thread, location, request));
}
}
} else if (stepType != null) {
List stepRequests = eventRequestManager.stepRequests();
for (Iterator iterator = stepRequests.iterator(); iterator.hasNext();) {
StepRequestImpl request = (StepRequestImpl) iterator.next();
ThreadReference requestThread = request.thread();
if (request.isEnabled() && (requestThread == null || thread == requestThread)) {
eventSet.add(new StepEventImpl(vm, thread, location, request));
}
}
}
Boolean debuggerStatement = (Boolean) event.getBody().get(JSONConstants.DEBUGGER_STATEMENT);
if (debuggerStatement.booleanValue()) {
List debuggerStatementRequests = eventRequestManager.debuggerStatementRequests();
for (Iterator iterator = debuggerStatementRequests.iterator(); iterator.hasNext();) {
DebuggerStatementRequestImpl request = (DebuggerStatementRequestImpl) iterator.next();
ThreadReference requestThread = request.thread();
if (request.isEnabled() && (requestThread == null || thread == requestThread)) {
eventSet.add(new DebuggerStatementEventImpl(vm, thread, location, request));
}
}
}
if (!eventSet.isEmpty()) {
thread.markSuspended(atBreakpoint);
}
}
} else if (eventName.equals(JSONConstants.EXCEPTION)) {
Long threadId = new Long(((Number) event.getBody().get(JSONConstants.THREAD_ID)).longValue());
ThreadReferenceImpl thread = vm.getThread(threadId);
if(thread != null) {
eventSet.setThread(thread);
Long scriptId = new Long(((Number) event.getBody().get(JSONConstants.SCRIPT_ID)).longValue());
ScriptReferenceImpl script = vm.getScript(scriptId);
int lineNumber = ((Number) event.getBody().get(JSONConstants.LINE)).intValue();
Location location = script.lineLocation(lineNumber);
String message = (String) event.getBody().get(JSONConstants.MESSAGE);
List exceptionRequests = eventRequestManager.exceptionRequests();
for (Iterator iterator = exceptionRequests.iterator(); iterator.hasNext();) {
ExceptionRequest request = (ExceptionRequest) iterator.next();
if (request.isEnabled()) {
eventSet.add(new ExceptionEventImpl(vm, thread, location, message, request));
}
}
if (!eventSet.isEmpty()) {
thread.markSuspended(false);
}
}
} else if (eventName.equals(JSONConstants.THREAD)) {
Long threadId = new Long(((Number) event.getBody().get(JSONConstants.THREAD_ID)).longValue());
String type = (String) event.getBody().get(JSONConstants.TYPE);
if (JSONConstants.ENTER.equals(type)) {
ThreadReferenceImpl thread = vm.getThread(threadId);
if(thread != null) {
eventSet.setThread(thread);
List threadEnterRequests = eventRequestManager.threadEnterRequests();
for (Iterator iterator = threadEnterRequests.iterator(); iterator.hasNext();) {
ThreadEnterRequest request = (ThreadEnterRequest) iterator.next();
if (request.isEnabled()) {
eventSet.add(new ThreadEnterEventImpl(vm, thread, request));
}
}
}
} else if (JSONConstants.EXIT.equals(type)) {
ThreadReferenceImpl thread = vm.removeThread(threadId);
List threadExitRequests = eventRequestManager.threadExitRequests();
for (Iterator iterator = threadExitRequests.iterator(); iterator.hasNext();) {
ThreadExitRequest request = (ThreadExitRequest) iterator.next();
if (request.isEnabled()) {
eventSet.add(new ThreadExitEventImpl(vm, thread, request));
}
}
}
else if(JSONConstants.VMDEATH.equals(type)) {
List requests = eventRequestManager.vmDeathRequests();
for (Iterator iter = requests.iterator(); iter.hasNext();) {
VMDeathRequest request = (VMDeathRequest) iter.next();
if(request.isEnabled()) {
eventSet.add(new VMDeathEventImpl(vm, request));
}
}
}
}
if (eventSet.isEmpty()) {
eventSet.resume();
continue;
}
return eventSet;
}
} catch (TimeoutException e) {
RhinoDebugPlugin.log(e);
} catch (DisconnectedException e) {
vm.disconnectVM();
handleException(e.getMessage(), e);
}
return null;
}
}