package org.jactr.tools.marker.tracer;
/*
* default logging
*/
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executor;
import javolution.util.FastList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.core.model.IModel;
import org.jactr.tools.marker.IMarkerListener;
import org.jactr.tools.marker.MarkerManager;
import org.jactr.tools.marker.impl.MarkerEvent;
import org.jactr.tools.tracer.ITraceSink;
import org.jactr.tools.tracer.listeners.BaseTraceListener;
import org.jactr.tools.tracer.sinks.ChainedSink;
import org.jactr.tools.tracer.sinks.trace.ArchivalSink;
public class MarkerTraceListener extends BaseTraceListener
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(MarkerTraceListener.class);
private final IMarkerListener _markerListener;
private MarkerIndex _markerIndex;
private final Set<IModel> _installedModels = new HashSet<IModel>();
public MarkerTraceListener()
{
_markerListener = new IMarkerListener() {
public void markerOpened(MarkerEvent me)
{
redirectEvent(me);
if (_markerIndex != null) _markerIndex.opened(me.getMarker());
}
public void markerClosed(MarkerEvent me)
{
redirectEvent(me);
if (_markerIndex != null) _markerIndex.closed(me.getMarker());
}
};
setEventTransformer(new MarkerEventTransformer());
}
public void install(IModel model, Executor executor)
{
MarkerManager.get().addListener(_markerListener, executor);
_installedModels.add(model);
}
public void uninstall(IModel model)
{
/*
* since we do a multi install, we need to make sure we only dispose of the
* tool once it has been removed from all
*/
if (_installedModels.remove(model) && _installedModels.size() == 0)
{
MarkerManager.get().removeListener(_markerListener);
if (_markerIndex != null)
{
_markerIndex.dispose();
_markerIndex = null;
}
}
}
@Override
public void setTraceSink(ITraceSink sink)
{
if (_markerIndex != null)
{
_markerIndex.dispose();
_markerIndex = null;
}
super.setTraceSink(sink);
if (_markerIndex == null)
{
ArchivalSink as = checkForArchivalSink(sink);
if (as != null) useIndexer(as);
}
}
protected ArchivalSink checkForArchivalSink(ITraceSink sink)
{
if (sink instanceof ArchivalSink) return (ArchivalSink) sink;
if (sink instanceof ChainedSink)
{
ChainedSink cSink = (ChainedSink) sink;
FastList<ITraceSink> sinks = FastList.newInstance();
cSink.getSinks(sinks);
try
{
for (ITraceSink tSink : sinks)
{
ArchivalSink as = checkForArchivalSink(tSink);
if (as != null) return as;
}
}
finally
{
FastList.recycle(sinks);
}
}
return null;
}
protected void useIndexer(ArchivalSink as)
{
_markerIndex = new MarkerIndex(as.getOutputDirectory());
}
}