package org.jactr.eclipse.runtime.ui.misc;
/*
* default logging
*/
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Executor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.jactr.eclipse.runtime.RuntimePlugin;
import org.jactr.eclipse.runtime.session.ISession;
import org.jactr.eclipse.runtime.session.ISessionListener;
import org.jactr.eclipse.runtime.session.data.ISessionData;
import org.jactr.eclipse.runtime.session.manager.ISessionManagerListener;
import org.jactr.eclipse.runtime.session.stream.ISessionDataStream;
import org.jactr.eclipse.ui.concurrent.SWTExecutor;
import org.jactr.eclipse.ui.generic.view.AbstractModelViewPart;
/**
* provides session control and a folder for displaying session/model data.
*
* @author harrison
*/
public abstract class AbstractRuntimeModelViewPart extends
AbstractModelViewPart implements ISessionSelectionProvider
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(AbstractRuntimeModelViewPart.class);
private ISessionManagerListener _sessionManagerListener;
private BasicSessionSelectionProvider _selectionProvider;
private TerminateAction _terminateAction;
private PlayPauseAction _playPauseAction;
private SelectSessionAction _sessionSelector;
private IDebugEventSetListener _debugListener;
private final ISessionSelectionListener _selectionListener;
private ISessionListener _sessionListener = new ISessionListener() {
public void sessionClosed(
ISession session)
{
}
public void sessionDestroyed(
ISession session)
{
}
public void newSessionData(
final ISessionData sessionData)
{
AbstractRuntimeModelViewPart.this
.newSessionData(sessionData);
}
public void newSessionDataStream(
ISessionData sessionData,
ISessionDataStream sessionDataStream)
{
AbstractRuntimeModelViewPart.this
.newSessionDataStream(
sessionData,
sessionDataStream);
}
};
private Set<ISessionData> _allSessionData;
public AbstractRuntimeModelViewPart()
{
_selectionProvider = new BasicSessionSelectionProvider();
_selectionListener = new ISessionSelectionListener() {
public void sessionSelected(ISession session)
{
try
{
/*
* if this session is the same as the selected tab, do nothing.
*/
ISession currentlySelected = getSelectedSession();
if (currentlySelected == session) return;
/*
* otherwise, find the first tab with a matching session
*/
CTabFolder folder = getTabFolder();
for (CTabItem item : folder.getItems())
{
ISessionData sessionData = (ISessionData) item.getData();
if (sessionData.getSession() == session)
{
setSelectedTab(item);
return;
}
}
}
finally
{
modifyActionAvailability();
modifyClosability();
}
}
};
addListener(_selectionListener, new SWTExecutor());
_allSessionData = new HashSet<ISessionData>();
_debugListener = new IDebugEventSetListener() {
public void handleDebugEvents(DebugEvent[] events)
{
boolean shouldUpdate = false;
for (DebugEvent event : events)
{
int kind = event.getKind();
shouldUpdate |= kind == DebugEvent.RESUME
|| kind == DebugEvent.SUSPEND || kind == DebugEvent.TERMINATE;
if (shouldUpdate) break;
}
if (shouldUpdate) Display.getDefault().asyncExec(new Runnable() {
public void run()
{
modifyActionAvailability();
modifyClosability();
}
});
}
};
_sessionManagerListener = new ISessionManagerListener() {
public void sessionAdded(ISession session)
{
addSession(session);
}
public void sessionRemoved(ISession session)
{
removeSession(session);
}
};
}
@Override
public void init(IViewSite site) throws PartInitException
{
super.init(site);
RuntimePlugin.getDefault().getSessionManager()
.addListener(_sessionManagerListener, null);
}
@Override
protected void partControlCreated()
{
addExistingSessionData();
}
public void addListener(ISessionSelectionListener listener, Executor executor)
{
_selectionProvider.addListener(listener, executor);
}
public void removeListener(ISessionSelectionListener listener)
{
_selectionProvider.removeListener(listener);
}
public void select(ISession session)
{
_selectionProvider.select(session);
}
public ISession getSelection()
{
return _selectionProvider.getSelection();
}
protected void addExistingSessionData()
{
/*
* now we should prepopulate with known models
*/
Set<ISession> sessions = new HashSet<ISession>();
RuntimePlugin.getDefault().getSessionManager().getSessions(sessions);
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("(%s) Addingin %d existing sessions",
getClass().getName(), sessions.size()));
for (ISession session : sessions)
addSession(session);
}
protected void addSession(ISession session)
{
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("(%s) session added %s", getClass().getName(),
session));
/*
* it is actually possible for the session not to be fully open yet, as it
* waits for the runtime to connect..
*/
// if (session.isOpen())
// {
session.addListener(_sessionListener, null);
for (String model : session.getKeys(new TreeSet<String>()))
{
ISessionData data = session.getData(model);
if (data != null && !_allSessionData.contains(data))
{
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("(%s) Adding %s", getClass().getName(),
model));
addModelData(model, data);
}
else if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("(%s) No data for %s, ignoring",
getClass().getName(), model));
}
// }
// else //not open? it's already closed?
// if (LOGGER.isWarnEnabled())
// LOGGER.warn(String.format("Session has already closed? %s", session));
}
protected void removeSession(ISession session)
{
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("Removing session %s", session));
session.removeListener(_sessionListener);
for (String model : session.getKeys(new TreeSet<String>()))
{
ISessionData data = session.getData(model);
if (data != null && _allSessionData.contains(data))
removeModelData(data);
}
}
@Override
protected void modelDataAdded(Object modelData)
{
_allSessionData.add((ISessionData) modelData);
select(((ISessionData) modelData).getSession());
}
@Override
protected void modelDataRemoved(Object modelData)
{
_allSessionData.remove(modelData);
ISessionData sessionData = (ISessionData) modelData;
if (sessionData.getSession() == getSelection())
{
ISession newSession = getSelectedSession();
select(newSession);
}
}
@Override
public String addModelData(String modelName, Object modelData)
{
if (_allSessionData.contains(modelData))
{
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("(%s) already has sessionData for %s",
getClass().getName(), modelData));
return null;
}
return super.addModelData(modelName, modelData);
}
/**
* called when new session data is available for a session we are tracking
*
* @param sessionData
*/
protected void newSessionData(ISessionData sessionData)
{
}
protected void newSessionDataStream(ISessionData sessionData,
ISessionDataStream sessionDataStream)
{
}
@Override
protected void createModelViewsFolder(Composite parent)
{
super.createModelViewsFolder(parent);
configureModelControl();
}
protected void configureModelControl()
{
// add debug listener
DebugPlugin.getDefault().addDebugEventListener(_debugListener);
CTabFolder folder = getTabFolder();
folder.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e)
{
tabSelected(getSelectedTab());
}
public void widgetSelected(SelectionEvent e)
{
tabSelected(getSelectedTab());
}
});
createActions();
createToolbar();
}
protected void tabSelected(CTabItem item)
{
ISession session = getSelectedSession();
/*
* send out the notification
*/
select(session);
}
@Override
public void setFocus()
{
// super.setFocus();
modifyActionAvailability();
modifyClosability();
}
@Override
public void dispose()
{
DebugPlugin.getDefault().removeDebugEventListener(_debugListener);
RuntimePlugin.getDefault().getSessionManager()
.removeListener(_sessionManagerListener);
super.dispose();
}
/**
* called when a tab is closed. Currently this will trigger a session wide
* close/destroy
*
* @param sessionData
*/
@Override
protected void tabClosed(Object modelData)
{
ISessionData sessionData = (ISessionData) modelData;
if (sessionData == null)
{
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("No session data available?"));
return;
}
ISession session = sessionData.getSession();
if (session == null) return;
if (session.isOpen())
{
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("Closing session"));
session.close();
}
if (!session.hasBeenDestroyed())
{
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("Destroying session", session));
session.destroy();
}
if (session == getSelection()) select(null);
}
protected void modifyClosability()
{
for (CTabItem item : getItems())
if (!item.isDisposed())
{
ISessionData sessionData = (ISessionData) item.getData();
if (sessionData == null)
{
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("No session data to interogate : %s",
item.getText()));
item.setShowClose(true);
}
else
item.setShowClose(!sessionData.getSession().isOpen());
}
}
protected ISessionData getSelectedSessionData()
{
CTabItem tab = getSelectedTab();
if (tab == null || tab.isDisposed()) return null;
return (ISessionData) tab.getData();
}
/**
* returns the session for the currently selected tab
*
* @return
*/
protected ISession getSelectedSession()
{
ISessionData data = getSelectedSessionData();
if (data != null) return data.getSession();
return null;
}
protected void modifyActionAvailability()
{
IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
_playPauseAction.refresh();
_terminateAction.refresh();
mgr.update(true);
}
private void createActions()
{
_playPauseAction = new PlayPauseAction();
_terminateAction = new TerminateAction();
_sessionSelector = new SelectSessionAction(this);
addListener(_playPauseAction, new SWTExecutor());
addListener(_terminateAction, new SWTExecutor());
}
private void createToolbar()
{
IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
mgr.add(_sessionSelector);
mgr.add(_terminateAction);
mgr.add(_playPauseAction);
}
}