package org.jactr.tools.experiment.parser;
/*
* default logging
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.tools.experiment.IExperiment;
import org.jactr.tools.experiment.actions.IAction;
import org.jactr.tools.experiment.actions.ICompositeAction;
import org.jactr.tools.experiment.parser.handlers.ActionHandlerHandler;
import org.jactr.tools.experiment.parser.handlers.AliasesHandler;
import org.jactr.tools.experiment.parser.handlers.ClearModelHandler;
import org.jactr.tools.experiment.parser.handlers.DataCollectorInitHandler;
import org.jactr.tools.experiment.parser.handlers.DataLoggerHandler;
import org.jactr.tools.experiment.parser.handlers.EndExperimentHandler;
import org.jactr.tools.experiment.parser.handlers.EndHandler;
import org.jactr.tools.experiment.parser.handlers.EndTrialHandler;
import org.jactr.tools.experiment.parser.handlers.FireNamedHandler;
import org.jactr.tools.experiment.parser.handlers.GroupHandler;
import org.jactr.tools.experiment.parser.handlers.INodeHandler;
import org.jactr.tools.experiment.parser.handlers.IfHandler;
import org.jactr.tools.experiment.parser.handlers.LockHandler;
import org.jactr.tools.experiment.parser.handlers.LogHandler;
import org.jactr.tools.experiment.parser.handlers.MarkerCloseHandler;
import org.jactr.tools.experiment.parser.handlers.MarkerOpenHandler;
import org.jactr.tools.experiment.parser.handlers.NextTrialHandler;
import org.jactr.tools.experiment.parser.handlers.ProxyActionHandler;
import org.jactr.tools.experiment.parser.handlers.RecordHandler;
import org.jactr.tools.experiment.parser.handlers.RewardModelHandler;
import org.jactr.tools.experiment.parser.handlers.SetValueHandler;
import org.jactr.tools.experiment.parser.handlers.StartHandler;
import org.jactr.tools.experiment.parser.handlers.StopModelHandler;
import org.jactr.tools.experiment.parser.handlers.TerminateRuntimeHandler;
import org.jactr.tools.experiment.parser.handlers.TimeTriggerHandler;
import org.jactr.tools.experiment.parser.handlers.TrialHandler;
import org.jactr.tools.experiment.parser.handlers.TrialHandlerHandler;
import org.jactr.tools.experiment.parser.handlers.TriggerHandler;
import org.jactr.tools.experiment.parser.handlers.TriggerHandlerHandler;
import org.jactr.tools.experiment.parser.handlers.UnlockHandler;
import org.jactr.tools.experiment.parser.handlers.WaitForACTRHandler;
import org.jactr.tools.experiment.trial.ICompoundTrial;
import org.jactr.tools.experiment.trial.ITrial;
import org.jactr.tools.experiment.triggers.EndTrigger;
import org.jactr.tools.experiment.triggers.ITrigger;
import org.jactr.tools.experiment.triggers.StartTrigger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class ExperimentParser
{
/**
* Logger definition
*/
static final public transient Log LOGGER = LogFactory
.getLog(ExperimentParser.class);
private Map<String, INodeHandler<ITrial>> _trialProcessors;
private Map<String, INodeHandler<IAction>> _actionProcessors;
private Map<String, INodeHandler<ITrigger>> _triggerProcessors;
public int _trialCount;
private IExperiment _experiment;
public ExperimentParser()
{
_trialProcessors = new TreeMap<String, INodeHandler<ITrial>>();
_triggerProcessors = new TreeMap<String, INodeHandler<ITrigger>>();
_actionProcessors = new TreeMap<String, INodeHandler<IAction>>();
initialize();
}
protected void initialize()
{
addActionHandler(new MarkerOpenHandler());
addActionHandler(new MarkerCloseHandler());
addTrialHandler(new TrialHandlerHandler(this));
addTrialHandler(new ActionHandlerHandler(this));
addTrialHandler(new TriggerHandlerHandler(this));
addTrialHandler(new DataLoggerHandler());
addTrialHandler(new DataCollectorInitHandler());
addTrialHandler(new AliasesHandler());
addTrialHandler(new GroupHandler(this));
addTrialHandler(new TrialHandler(this));
addTriggerHandler(new TriggerHandler());
addTriggerHandler(new StartHandler());
addTriggerHandler(new EndHandler());
addTriggerHandler(new TimeTriggerHandler());
addActionHandler(new FireNamedHandler());
addActionHandler(new NextTrialHandler());
addActionHandler(new EndTrialHandler());
addActionHandler(new ClearModelHandler());
addActionHandler(new RewardModelHandler());
addActionHandler(new LogHandler());
addActionHandler(new RecordHandler());
addActionHandler(new EndExperimentHandler());
addActionHandler(new TerminateRuntimeHandler());
addActionHandler(new StopModelHandler());
addActionHandler(new ProxyActionHandler());
addActionHandler(new WaitForACTRHandler());
addActionHandler(new LockHandler());
addActionHandler(new UnlockHandler());
addActionHandler(new SetValueHandler());
addActionHandler(new IfHandler());
}
public void addTrialHandler(INodeHandler<ITrial> handler)
{
_trialProcessors.put(handler.getTagName(), handler);
}
public void addActionHandler(INodeHandler<IAction> handler)
{
_actionProcessors.put(handler.getTagName(), handler);
}
public void addTriggerHandler(INodeHandler<ITrigger> handler)
{
_triggerProcessors.put(handler.getTagName(), handler);
}
protected INodeHandler<ITrigger> getTriggerHandler(String tagName)
{
return _triggerProcessors.get(tagName);
}
protected INodeHandler<ITrial> getTrialHandler(String tagName)
{
return _trialProcessors.get(tagName);
}
protected INodeHandler<IAction> getActionHandler(String tagName)
{
return _actionProcessors.get(tagName);
}
public void configure(Document document, IExperiment experiment)
{
_experiment = experiment;
int iterations = 1;
String itrStr = null;
try
{
itrStr = _experiment.getVariableResolver().resolve(
document.getDocumentElement().getAttribute("iterations"),
experiment.getVariableContext()).toString();
iterations = Integer.parseInt(itrStr);
}
catch (Exception e)
{
LOGGER.error("Failed to process " + itrStr + " into integer, using 1", e);
iterations = 1;
}
NodeList children = document.getDocumentElement().getChildNodes();
boolean first = true;
while (iterations > 0)
{
for (int i = 0; i < children.getLength(); i++)
{
Node node = children.item(i);
if (node instanceof Element)
{
Object rtn = processNode((Element) node);
if (rtn instanceof ITrial)
_experiment.addTrial((ITrial) rtn);
else if (first && (rtn instanceof ITrigger))
{
/*
* only add the triggers once..
*/
if (rtn instanceof StartTrigger)
_experiment.setStartTrigger((StartTrigger) rtn);
else if (rtn instanceof EndTrigger)
_experiment.setEndTrigger((EndTrigger) rtn);
else
_experiment.addTrigger((ITrigger) rtn);
}
}
}
iterations--;
first = false;
}
}
protected Object processNode(Element element)
{
INodeHandler<ITrial> tHandler = getTrialHandler(element.getTagName());
if (tHandler != null)
{
ITrial trial = tHandler.process(element, _experiment);
if (tHandler.shouldDecend())
return processTrial(trial, element);
else
return trial;
}
INodeHandler<ITrigger> trHandler = getTriggerHandler(element.getTagName());
if (trHandler != null)
{
ITrigger trigger = trHandler.process(element, _experiment);
if (trHandler.shouldDecend())
return processTrigger(trigger, element);
else
return trigger;
}
INodeHandler<IAction> aHandler = getActionHandler(element.getTagName());
if (aHandler != null)
{
IAction action = aHandler.process(element, _experiment);
if (aHandler.shouldDecend())
return processAction(action, element);
else
return action;
}
if (LOGGER.isWarnEnabled())
LOGGER.warn("No clue how to process " + element.getTagName());
Collection container = new ArrayList();
NodeList list = element.getChildNodes();
for (int i = 0; i < list.getLength(); i++)
{
Node node = list.item(i);
if (!(node instanceof Element)) continue;
Element nodeElement = (Element) node;
Object thing = processNode(nodeElement);
if (thing != null) container.add(thing);
}
return container;
}
/*
* should probably move this into the individual processors..
*/
protected ITrial processTrial(ITrial trial, Element element)
{
NodeList list = element.getChildNodes();
for (int i = 0; i < list.getLength(); i++)
{
Node node = list.item(i);
if (!(node instanceof Element)) continue;
Element nodeElement = (Element) node;
Object rtn = processNode(nodeElement);
if (rtn instanceof ITrigger)
{
if (rtn instanceof StartTrigger)
trial.setStartTrigger((ITrigger) rtn);
else if (rtn instanceof EndTrigger)
trial.setEndTrigger((ITrigger) rtn);
else
trial.addTrigger((ITrigger) rtn);
}
else if (rtn instanceof ITrial && trial instanceof ICompoundTrial)
{
((ICompoundTrial) trial).add((ITrial) rtn);
}
else if (rtn != null)
if (LOGGER.isWarnEnabled())
LOGGER.warn(String.format("No clue what to do with %s from %s", rtn, nodeElement.getTagName()));
}
return trial;
}
protected ITrigger processTrigger(ITrigger trigger, Element element)
{
NodeList list = element.getChildNodes();
for (int i = 0; i < list.getLength(); i++)
{
Node node = list.item(i);
if (!(node instanceof Element)) continue;
Element nodeElement = (Element) node;
Object rtn = processNode(nodeElement);
if (rtn instanceof IAction)
trigger.add((IAction) rtn);
else if (rtn instanceof ITrigger)
trigger.add((ITrigger) rtn);
else if (rtn != null)
if (LOGGER.isWarnEnabled())
LOGGER.warn(String.format("No clue what to do with %s from %s", rtn, nodeElement.getTagName()));
}
return trigger;
}
protected IAction processAction(IAction action, Element element)
{
if (action instanceof ICompositeAction)
{
ICompositeAction cAction = (ICompositeAction) action;
NodeList list = element.getChildNodes();
for (int i = 0; i < list.getLength(); i++)
{
Node node = list.item(i);
if (!(node instanceof Element)) continue;
Element nodeElement = (Element) node;
Object rtn = processNode(nodeElement);
if (rtn instanceof IAction)
cAction.add((IAction) rtn);
else if (rtn != null)
if (LOGGER.isWarnEnabled())
LOGGER.warn(String.format("No clue what to do with %s from %s", rtn, nodeElement.getTagName()));
}
}
return action;
}
}