package org.jactr.tools.tracer.listeners; /* * default logging */ import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.Executor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jactr.core.logging.ILogger; import org.jactr.core.logging.LogEvent; import org.jactr.core.logging.Logger; import org.jactr.core.model.IModel; import org.jactr.core.model.event.IModelListener; import org.jactr.core.model.event.ModelEvent; import org.jactr.core.model.event.ModelListenerAdaptor; import org.jactr.core.module.procedural.event.IProceduralModuleListener; import org.jactr.core.module.procedural.event.ProceduralModuleEvent; import org.jactr.core.module.procedural.event.ProceduralModuleListenerAdaptor; import org.jactr.tools.tracer.transformer.logging.BulkLogEvent; public class LogTracer extends BaseTraceListener implements ILogger { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(LogTracer.class); private IModelListener _modelListener; private IProceduralModuleListener _proceduralListener; private Map<IModel, Map<String, StringBuilder>> _logData; public LogTracer() { _logData = new HashMap<IModel, Map<String, StringBuilder>>(); _proceduralListener = new ProceduralModuleListenerAdaptor() { /* * middle flush (non-Javadoc) * @see * org.jactr.core.module.procedural.event.ProceduralModuleListenerAdaptor * #productionWillFire * (org.jactr.core.module.procedural.event.ProceduralModuleEvent) */ @Override public void conflictSetAssembled(ProceduralModuleEvent pme) { flushToSink(pme.getSource().getModel(), pme.getSimulationTime(), false); } }; _modelListener = new ModelListenerAdaptor() { /* * end flush (non-Javadoc) * @see * org.jactr.core.model.event.ModelListenerAdaptor#cycleStopped(org.jactr * .core.model.event.ModelEvent) */ @Override public void cycleStopped(ModelEvent me) { flushToSink(me.getSource(), me.getSimulationTime(), true); } }; } public void install(IModel model, Executor executor) { _logData.put(model, new TreeMap<String, StringBuilder>()); Logger.addLogger(model, this, executor); model.addListener(_modelListener, executor); model.getProceduralModule().addListener(_proceduralListener, executor); } public void uninstall(IModel model) { _logData.remove(model); Logger.removeLogger(model, this); model.removeListener(_modelListener); model.getProceduralModule().removeListener(_proceduralListener); } synchronized public void log(LogEvent logEvent) { /* * concatenate */ Map<String, StringBuilder> logMap = _logData.get(logEvent.getModel()); StringBuilder log = logMap.get(logEvent.getStreamName()); if (log == null) { log = new StringBuilder(); logMap.put(logEvent.getStreamName(), log); } log.append(logEvent.getMessage()).append("\n"); } synchronized protected void flushToSink(IModel model, double time, boolean endOfCycle) { Map<String, StringBuilder> logMap = _logData.get(model); BulkLogEvent ble = new BulkLogEvent(model.getName(), time, logMap, endOfCycle); sink(ble); // clear for (StringBuilder sb : logMap.values()) sb.delete(0, sb.length()); } public void flush() { // noop } }