blob: 6c40a43b58e4a5c5e5dec587016aa5bef387eaca [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.crossfire.event;
import java.util.Iterator;
import java.util.List;
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.EventRequestManager;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ScriptLoadRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.SuspendRequest;
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.crossfire.CrossFirePlugin;
import org.eclipse.wst.jsdt.debug.internal.crossfire.Tracing;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFLocation;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFMirror;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFScriptReference;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFThreadReference;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFVirtualMachine;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.Attributes;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.DisconnectedException;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.Event;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.JSON;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.TimeoutException;
/**
* Default {@link EventQueue} for Crossfire
*
* @since 1.0
*/
public class CFEventQueue extends CFMirror implements EventQueue {
private static boolean TRACE = false;
private EventRequestManager eventmgr = null;
private boolean disposed = false;
/**
* Constructor
*
* @param vm
* @param manager
*/
public CFEventQueue(CFVirtualMachine vm, EventRequestManager manager) {
super(vm);
this.eventmgr = manager;
}
/* (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 && !disposed) {
Event event = crossfire().receiveEvent(timeout);
String name = event.getEvent();
CFEventSet set = new CFEventSet(crossfire());
if(Event.CLOSED.equals(name)) {
List deaths = eventmgr.vmDeathRequests();
for (Iterator iter = deaths.iterator(); iter.hasNext();) {
VMDeathRequest request = (VMDeathRequest) iter.next();
set.add(new CFVMDeathEvent(crossfire(), request));
}
crossfire().terminate();
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.CLOSED+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_BREAK.equals(name)) {
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_BREAK+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
String threadid = event.getContextId();
if(threadid != null) {
CFThreadReference thread = crossfire().findThread(threadid);
set.setThread(thread);
if(thread != null && !thread.isSuspended()) {
List suspends = eventmgr.suspendRequests();
for (Iterator iter = suspends.iterator(); iter.hasNext();) {
SuspendRequest request = (SuspendRequest) iter.next();
String url = (String) event.getBody().get(Attributes.URL);
Number line = (Number) event.getBody().get(Attributes.LINE);
CFScriptReference script = crossfire().findScript(url);
if(script != null) {
CFLocation loc = new CFLocation(crossfire(), script, null, line.intValue());
set.add(new CFSuspendEvent(crossfire(), request, thread, loc));
}
}
thread.markSuspended(true);
}
return null;
}
}
else if(Event.ON_RESUME.equals(name)) {
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_RESUME+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
String threadid = event.getContextId();
if(threadid != null) {
CFThreadReference thread = crossfire().findThread(threadid);
set.setThread(thread);
if(thread != null && thread.isSuspended()) {
thread.markSuspended(false);
}
return null;
}
}
else if(Event.ON_SCRIPT.equals(name)) {
ThreadReference thread = crossfire().findThread(event.getContextId());
if(thread != null) {
set.setThread(thread);
CFScriptReference script = crossfire().addScript(event.getContextId(), event.getBody());
List scripts = eventmgr.scriptLoadRequests();
for (Iterator iter = scripts.iterator(); iter.hasNext();) {
ScriptLoadRequest request = (ScriptLoadRequest) iter.next();
set.add(new CFScriptLoadEvent(crossfire(), request, thread, script));
}
}
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_SCRIPT+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_CONTEXT_CREATED.equals(name)) {
List threads = eventmgr.threadEnterRequests();
CFThreadReference thread = crossfire().addThread(event.getContextId(), (String) event.getBody().get(Attributes.HREF));
set.setThread(thread);
for (Iterator iter = threads.iterator(); iter.hasNext();) {
ThreadEnterRequest request = (ThreadEnterRequest) iter.next();
set.add(new CFThreadEnterEvent(crossfire(), request, thread));
}
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_CONTEXT_CREATED+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_CONTEXT_DESTROYED.equals(name)) {
ThreadReference thread = crossfire().findThread(event.getContextId());
crossfire().removeThread(event.getContextId());
if(thread != null) {
List threads = eventmgr.threadExitRequests();
for (Iterator iter = threads.iterator(); iter.hasNext();) {
ThreadExitRequest request = (ThreadExitRequest) iter.next();
set.add(new CFThreadExitEvent(crossfire(), request, thread));
}
}
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_CONTEXT_DESTROYED+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_CONSOLE_DEBUG.equals(name)) {
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_CONSOLE_DEBUG+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_CONSOLE_ERROR.equals(name)) {
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_CONSOLE_ERROR+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_CONSOLE_INFO.equals(name)) {
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_CONSOLE_INFO+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_CONSOLE_LOG.equals(name)) {
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_CONSOLE_LOG+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_CONSOLE_WARN.equals(name)) {
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_CONSOLE_WARN+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_INSPECT_NODE.equals(name)) {
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_INSPECT_NODE+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else if(Event.ON_TOGGLE_BREAKPOINT.equals(name)) {
if(TRACE) {
Tracing.writeString("QUEUE [event - "+Event.ON_TOGGLE_BREAKPOINT+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else {
if(TRACE) {
Tracing.writeString("QUEUE [unknown event - "+name+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
if (set.isEmpty()) {
set.resume();
continue;
}
return set;
}
}
catch(DisconnectedException de) {
if(TRACE) {
Tracing.writeString("QUEUE [disconnect exception]: "+de.getMessage()); //$NON-NLS-1$
}
crossfire().disconnectVM();
handleException(de.getMessage(), de);
}
catch(TimeoutException te) {
CrossFirePlugin.log(te);
}
return null;
}
/**
* Flushes and cleans up the queue
*/
public void dispose() {
disposed = true;
}
/**
* Turns on / off tracing in the event queue
* @param tracing
*/
public static void setTracing(boolean tracing) {
TRACE = tracing;
}
}