/******************************************************************************
* Copyright (c) 2007, 2008 Edgar Espina.
* 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
*
*******************************************************************************/
package org.deved.antlride.internal.debug.ui;
import java.util.ArrayList;
import java.util.List;
import org.deved.antlride.debug.AntlrDebugConstants;
import org.deved.antlride.debug.model.AntlrDebugTarget;
import org.deved.antlride.debug.model.event.AntlrDebugEvent;
import org.deved.antlride.debug.model.event.AntlrDebugEventKind;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.ui.AbstractDebugView;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.debug.ui.contexts.IDebugContextManager;
import org.eclipse.debug.ui.contexts.IDebugContextService;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
public abstract class AntlrDebugView extends AbstractDebugView implements
ISelectionListener, ISelectionChangedListener, IDebugContextListener,
IDebugEventSetListener {
private final Object lock = new Object();
private boolean fTerminated;
private int fDecision;
private AntlrDebugEventFilter activeFilter = new AntlrDebugEventActiveFilter();
private AntlrDebugEventFilter inactiveFilter = new AntlrDebugEventInactiveFilter();
protected AntlrDebugTarget debugTarget;
private class OnStartTask implements Runnable {
private AntlrDebugTarget debugTarget;
public OnStartTask(AntlrDebugTarget debugTarget) {
this.debugTarget = debugTarget;
}
public void run() {
onStart(debugTarget);
}
}
private class OnTerminateTask implements Runnable {
private AntlrDebugTarget debugTarget;
public OnTerminateTask(AntlrDebugTarget debugTarget) {
this.debugTarget = debugTarget;
}
public void run() {
onTerminate(debugTarget);
}
}
private class SyncDebugEventTask implements Runnable {
private AntlrDebugEvent[] events;
public SyncDebugEventTask(AntlrDebugEvent[] events) {
this.events = events;
}
public void run() {
onDebugEvents(events);
}
}
private interface AntlrDebugEventFilter {
public boolean acceptEvent(AntlrDebugEvent event);
}
private class AntlrDebugEventActiveFilter implements AntlrDebugEventFilter{
public boolean acceptEvent(AntlrDebugEvent event) {
return canDispatchEvent(event);
}
}
private class AntlrDebugEventInactiveFilter implements AntlrDebugEventFilter{
public boolean acceptEvent(AntlrDebugEvent event) {
return accept(event);
}
}
public AntlrDebugView() {
}
private boolean canDispatchEvent(AntlrDebugEvent event) {
AntlrDebugTarget debugTarget = event.getDebugTarget();
if (!debugTarget.hasBreakpointsEnabled()) {
return false;
}
if (!debugTarget.isSuspended()) {
return false;
}
return accept(event);
}
private void dispatchEvents(AntlrDebugEvent[] events) {
syncExec(new SyncDebugEventTask(events));
}
protected abstract void onDebugEvents(AntlrDebugEvent[] events);
private void computeInput(ISelection selection) {
AntlrDebugTarget target = findDebugTarget(selection);
computeInput(target);
}
private void fireEvents(AntlrDebugTarget debugTarget, AntlrDebugEventFilter filter) {
List<AntlrDebugEvent> events = new ArrayList<AntlrDebugEvent>();
fDecision = 0;
for (int i = 0; i < debugTarget.getEventCount(); i++) {
AntlrDebugEvent e = debugTarget.getEvent(i);
AntlrDebugEventKind kind = e.getEventKind();
switch (kind) {
case ENTER_DECISION:
fDecision++;
break;
case EXIT_DECISION:
fDecision--;
break;
}
if (filter.acceptEvent(e)) {
events.add(e);
}
}
if (events.size() > 0) {
dispatchEvents(events.toArray(new AntlrDebugEvent[events.size()]));
}
events.clear();
events = null;
}
private void computeInput(AntlrDebugTarget debugTarget) {
synchronized (lock) {
if (debugTarget != null) {
fireEvents(debugTarget, activeFilter);
}
}
}
protected boolean accept(AntlrDebugEvent e) {
return true;
}
protected boolean isInDecision() {
return fDecision != 0;
}
private AntlrDebugTarget findDebugTarget(ISelection selection) {
Object object = null;
if (selection instanceof IStructuredSelection) {
IStructuredSelection sSelection = (IStructuredSelection) selection;
object = sSelection.getFirstElement();
}
return findDebugTarget(object);
}
private AntlrDebugTarget findDebugTarget(IAdaptable adaptable) {
AntlrDebugTarget debugTarget = null;
IDebugElement element = (IDebugElement) adaptable
.getAdapter(IDebugElement.class);
if (element != null) {
if (element.getModelIdentifier().equals(
AntlrDebugConstants.DEBUG_MODEL_ID)) {
debugTarget = (AntlrDebugTarget) element.getDebugTarget();
}
} else {
ILaunch launch = (ILaunch) adaptable.getAdapter(ILaunch.class);
if (launch != null) {
IDebugTarget[] debugTargets = launch.getDebugTargets();
for (IDebugTarget dt : debugTargets) {
if (dt instanceof AntlrDebugTarget) {
debugTarget = (AntlrDebugTarget) dt;
break;
}
}
}
}
return debugTarget;
}
private AntlrDebugTarget findDebugTarget(Object object) {
AntlrDebugTarget debugTarget = null;
if (object instanceof AntlrDebugTarget) {
debugTarget = (AntlrDebugTarget) object;
} else if (object instanceof AntlrDebugEvent) {
AntlrDebugEvent e = (AntlrDebugEvent) object;
debugTarget = e.getDebugTarget();
}
if (debugTarget == null) {
if (object instanceof IAdaptable) {
debugTarget = findDebugTarget((IAdaptable) object);
} else if (object == null) {
IAdaptable adaptable = DebugUITools.getDebugContext();
if (adaptable != null)
debugTarget = findDebugTarget(adaptable);
}
}
return debugTarget;
}
private boolean isAntlrDebugElement(ISelection selection) {
if (selection instanceof IStructuredSelection) {
Object o = ((IStructuredSelection) selection).getFirstElement();
if (o instanceof IAdaptable) {
IAdaptable adaptable = (IAdaptable) o;
IDebugElement element = (IDebugElement) adaptable
.getAdapter(IDebugElement.class);
if (element != null) {
return (element.getModelIdentifier()
.equals(AntlrDebugConstants.DEBUG_MODEL_ID));
}
}
}
return true;
}
@Override
protected void configureToolBar(IToolBarManager tbm) {
}
@Override
protected void createActions() {
}
protected Viewer createViewer(Composite parent) {
Viewer viewer = internalCreateViewer(parent);
fillActionBars(getViewSite().getActionBars());
// viewer.addSelectionChangedListener(this);
ISelectionService selectionService = getSelectionService();
selectionService.addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW,
this);
getSite().setSelectionProvider(viewer);
// getContextService().addDebugContextListener(this);
DebugPlugin.getDefault().addDebugEventListener(this);
return viewer;
}
protected void fillActionBars(IActionBars actionBars) {
IToolBarManager toolBar = actionBars.getToolBarManager();
fillToolBar(toolBar);
}
protected void fillToolBar(IToolBarManager toolBar) {
}
protected IDebugContextManager getDebugContextManager() {
return DebugUITools.getDebugContextManager();
}
protected IDebugContextService getContextService() {
return getDebugContextManager().getContextService(getWorkbenchWindow());
}
protected abstract Viewer internalCreateViewer(Composite parent);
@Override
protected void fillContextMenu(IMenuManager menu) {
}
@Override
protected String getHelpContextId() {
return null;
}
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
contextActivated(selection);
}
public void selectionChanged(SelectionChangedEvent event) {
contextActivated(event.getSelection());
}
public void debugContextChanged(DebugContextEvent event) {
if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
contextActivated(event.getContext());
}
}
protected void contextActivated(ISelection selection) {
if (!isAvailable() || !isAntlrDebugElement(selection)) {
return;
}
computeInput(selection);
}
public void handleDebugEvents(DebugEvent[] events) {
if (events != null && events.length > 0) {
DebugEvent event = events[0];
Object source = event.getSource();
if (source instanceof IDebugElement) {
IDebugElement element = (IDebugElement) event.getSource();
if (element.getModelIdentifier().equals(
AntlrDebugConstants.DEBUG_MODEL_ID)) {
AntlrDebugTarget debugTarget = (AntlrDebugTarget) element
.getDebugTarget();
if (event.getKind() == DebugEvent.CREATE) {
fTerminated = false;
syncExec(new OnStartTask(debugTarget));
computeInput(debugTarget);
} else if (event.getKind() == DebugEvent.TERMINATE) {
if (!fTerminated) {
fTerminated = true;
syncExec(new OnTerminateTask(debugTarget));
computeInput((AntlrDebugTarget) null);
}
}
}
}
}
}
protected void onStart(AntlrDebugTarget debugTarget) {
this.debugTarget = debugTarget;
}
protected void onTerminate(AntlrDebugTarget debugTarget) {
fireEvents(debugTarget, inactiveFilter);
}
protected IWorkbenchWindow getWorkbenchWindow() {
return getSite().getWorkbenchWindow();
}
protected ISelectionService getSelectionService() {
return getWorkbenchWindow().getSelectionService();
}
@Override
public void dispose() {
DebugUITools.getDebugContextManager().getContextService(
getWorkbenchWindow()).removeDebugContextListener(this);
ISelectionService selectionService = getSelectionService();
selectionService.removeSelectionListener(
IDebugUIConstants.ID_DEBUG_VIEW, this);
DebugPlugin.getDefault().removeDebugEventListener(this);
super.dispose();
}
}