package org.jactr.tools.experiment.actions.sensor; /* * default logging */ import java.net.URL; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javolution.util.FastList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.commonreality.reality.CommonReality; import org.commonreality.sensors.ISensor; import org.jactr.tools.experiment.IExperiment; import org.jactr.tools.experiment.actions.IAction; import org.jactr.tools.experiment.impl.IVariableContext; import org.jactr.tools.experiment.impl.VariableResolver; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class XMLSensorAction implements IAction { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(XMLSensorAction.class); private String _location; private IExperiment _experiment; private boolean _immediateExecution; private String _forWhom =""; public XMLSensorAction(String location, boolean executeImmediately, IExperiment experiment) { this(location, executeImmediately, experiment, ""); } public XMLSensorAction(String location, boolean executeImmediately, IExperiment experiment, String forWhom) { _location = location; _experiment = experiment; _immediateExecution = executeImmediately; _forWhom = forWhom; } protected Element transform(Element timeNode, IVariableContext context) { VariableResolver resolver = _experiment.getVariableResolver(); NamedNodeMap attrs = timeNode.getAttributes(); for (int i = 0; i < attrs.getLength(); i++) { Node attr = attrs.item(i); String nodeValue = attr.getNodeValue(); if (resolver.isVariable(nodeValue)) { nodeValue = resolver.resolve(nodeValue, context).toString(); attr.setNodeValue(nodeValue); } } /* * descend */ NodeList children = timeNode.getChildNodes(); for (int i = 0; i < children.getLength(); i++) if (children.item(i) instanceof Element) transform((Element) children.item(i), context); return timeNode; } public void fire(IVariableContext context) { context.set("modelName", _forWhom); String location = _experiment.getVariableResolver() .resolve(_location, context).toString(); URL loc = getClass().getClassLoader().getResource(location); if (loc == null) throw new IllegalArgumentException("Could not find resource url for " + _location + " [" + location + "]"); org.commonreality.sensors.xml2.XMLSensor newSensor = getSensor2(); org.commonreality.sensors.xml.XMLSensor oldSensor = getSensor(); if (newSensor == null && oldSensor == null) throw new IllegalStateException("Could not find XMLSensor"); try { if (!_immediateExecution) { // sensor.configure(Collections.singletonMap(XMLSensor.DATA_URL, // loc.toString())); if (newSensor != null) newSensor.load(loc); if (oldSensor != null) oldSensor.load(loc); } else { FastList<Element> elements = FastList.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder parser = factory.newDocumentBuilder(); Document doc = parser.parse(loc.openStream()); Element root = doc.getDocumentElement(); NodeList nl = root.getElementsByTagName("time"); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { if (oldSensor != null) oldSensor.executeFrameNow(transform((Element) node, context)); if (newSensor != null) elements.add(transform((Element) node, context)); } } if (newSensor != null) newSensor.flush(elements); FastList.recycle(elements); } } catch (Exception e) { throw new IllegalStateException("Unable to queue up sensor data ", e); } } private org.commonreality.sensors.xml.XMLSensor getSensor() { for (ISensor sensor : CommonReality.getSensors()) if (sensor instanceof org.commonreality.sensors.xml.XMLSensor) return (org.commonreality.sensors.xml.XMLSensor) sensor; return null; } private org.commonreality.sensors.xml2.XMLSensor getSensor2() { for (ISensor sensor : CommonReality.getSensors()) if (sensor instanceof org.commonreality.sensors.xml2.XMLSensor) return (org.commonreality.sensors.xml2.XMLSensor) sensor; return null; } }