summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
diff options
context:
space:
mode:
authorStefan Radomski <github@mintwerk.de>2016-05-12 13:12:33 (GMT)
committerStefan Radomski <github@mintwerk.de>2016-05-12 13:12:33 (GMT)
commitb62e7979600feee23dc7cdb61042a8fc7673122b (patch)
treef7351372f37979dd2d048e0b68a16a4cd3b2aadb /src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
parent1b11b310be61e51b3ac5ebb83f7c8a33aef3d6e8 (diff)
downloaduscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.zip
uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.gz
uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.bz2
Major Refactoring v2.0
Diffstat (limited to 'src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp')
-rw-r--r--src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp876
1 files changed, 0 insertions, 876 deletions
diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
deleted file mode 100644
index 282e8c6..0000000
--- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
+++ /dev/null
@@ -1,876 +0,0 @@
-/**
- * @file
- * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de)
- * @author 2013 Enrico Papi (enrico.papi@ajile.it)
- * @copyright Simplified BSD
- *
- * @cond
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the FreeBSD license as published by the FreeBSD
- * project.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the FreeBSD license along with this
- * program. If not, see <http://www.opensource.org/licenses/bsd-license>.
- * @endcond
- */
-
-#include "uscxml/Common.h"
-#include "XPathDataModel.h"
-
-#include "uscxml/Message.h"
-#include "uscxml/util/String.h"
-#include "uscxml/dom/DOMUtils.h"
-#include <glog/logging.h>
-#include <boost/algorithm/string.hpp>
-
-#include <DOM/SAX2DOM/SAX2DOM.hpp>
-//#include <SAX/helpers/CatchErrorHandler.hpp>
-//#include <DOM/Events/EventTarget.hpp>
-//#include <DOM/Events/EventListener.hpp>
-
-#ifdef BUILD_AS_PLUGINS
-#include <Pluma/Connector.hpp>
-#endif
-
-namespace uscxml {
-
-using namespace Arabica::XPath;
-using namespace Arabica::DOM;
-
-#ifdef BUILD_AS_PLUGINS
-PLUMA_CONNECTOR
-bool pluginConnect(pluma::Host& host) {
- host.add( new XPathDataModelProvider() );
- return true;
-}
-#endif
-
-XPathDataModel::XPathDataModel() {
-}
-
-boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterInfo* interpreter) {
- boost::shared_ptr<XPathDataModel> dm = boost::shared_ptr<XPathDataModel>(new XPathDataModel());
- dm->_interpreter = interpreter;
-
-// dm->_xpath->setVariableCompileTimeResolver(_varCTResolver);
-// dm->_xpath->setNamespaceContext(interpreter->getNSContext());
-
- dm->_funcResolver.setInterpreter(interpreter);
- dm->_xpath.setNamespaceContext(*interpreter->getNameSpaceInfo().getNSContext());
- dm->_xpath.setFunctionResolver(dm->_funcResolver);
- dm->_xpath.setVariableResolver(dm->_varResolver);
-
- dm->_domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
- dm->_doc = dm->_domFactory.createDocument("http://www.w3.org/2005/07/scxml", "", 0);
- dm->_datamodel = dm->_doc.createElement("datamodel");
- dm->_doc.appendChild(dm->_datamodel);
-
- Element<std::string> ioProcElem = dm->_doc.createElement("data");
- ioProcElem.setAttribute("id", "_ioprocessors");
- std::map<std::string, IOProcessor>::const_iterator ioProcIter = interpreter->getIOProcessors().begin();
- while(ioProcIter != interpreter->getIOProcessors().end()) {
- Element<std::string> ioProc = dm->_doc.createElement("processor");
- ioProc.setAttribute("name", ioProcIter->first);
-
- Data ioProcData = ioProcIter->second.getDataModelVariables();
- Element<std::string> ioProcLoc = dm->_doc.createElement("location");
- Text<std::string> ioProcLocText = dm->_doc.createTextNode(ioProcData.compound["location"].atom);
- ioProcLoc.appendChild(ioProcLocText);
- ioProc.appendChild(ioProcLoc);
- ioProcElem.appendChild(ioProc);
-
- ioProcIter++;
- }
- dm->_datamodel.appendChild(ioProcElem);
-
- NodeSet<std::string> ioProcNodeSet;
- ioProcNodeSet.push_back(ioProcElem);
- dm->_varResolver.setVariable("_ioprocessors", ioProcNodeSet);
-
- Element<std::string> sessIdElem = dm->_doc.createElement("data");
- sessIdElem.setAttribute("id", "_sessionid");
- Text<std::string> sessIdText = dm->_doc.createTextNode(interpreter->getSessionId());
- sessIdElem.appendChild(sessIdText);
- dm->_datamodel.appendChild(sessIdElem);
-
- NodeSet<std::string> sessIdNodeSet;
- sessIdNodeSet.push_back(sessIdText);
- dm->_varResolver.setVariable("_sessionid", sessIdNodeSet);
-
-
- Element<std::string> nameElem = dm->_doc.createElement("data");
- nameElem.setAttribute("id", "_name");
- Text<std::string> nameText = dm->_doc.createTextNode(interpreter->getName());
- nameElem.appendChild(nameText);
- dm->_datamodel.appendChild(nameElem);
-
- NodeSet<std::string> nameNodeSet;
- nameNodeSet.push_back(nameText);
- dm->_varResolver.setVariable("_name", nameNodeSet);
-
- return dm;
-}
-
-XPathDataModel::~XPathDataModel() {
-}
-
-void XPathDataModel::pushContext() {
-}
-
-void XPathDataModel::popContext() {
-}
-
-void XPathDataModel::initialize() {
-}
-
-void XPathDataModel::setEvent(const Event& event) {
- Element<std::string> eventElem = _doc.createElement("data");
- eventElem.setAttribute("id", "_event");
-
- Element<std::string> eventDataElem = _doc.createElement("data");
- NodeSet<std::string> eventNodeSet;
-
- {
- // -- name
- Element<std::string> eventNameElem = _doc.createElement("name");
- Text<std::string> eventName = _doc.createTextNode(event.name.c_str());
- eventNameElem.appendChild(eventName);
- eventElem.appendChild(eventNameElem);
- }
- {
- // -- origin
- Element<std::string> eventOriginElem = _doc.createElement("origin");
- Text<std::string> eventOrigin = _doc.createTextNode(event.origin.c_str());
- eventOriginElem.appendChild(eventOrigin);
- eventElem.appendChild(eventOriginElem);
- }
- {
- // -- type
- Element<std::string> eventTypeElem = _doc.createElement("type");
- Text<std::string> eventType;
- switch (event.eventType) {
- case Event::INTERNAL:
- eventType = _doc.createTextNode("internal");
- break;
- case Event::EXTERNAL:
- eventType = _doc.createTextNode("external");
- break;
- case Event::PLATFORM:
- eventType = _doc.createTextNode("platform");
- break;
- }
- eventTypeElem.appendChild(eventType);
- eventElem.appendChild(eventTypeElem);
- }
-
- if (event.params.size() > 0) {
- std::multimap<std::string, Data>::const_iterator paramIter = event.params.begin();
- while(paramIter != event.params.end()) {
- Element<std::string> eventParamElem = _doc.createElement("data");
- // this is simplified - Data might be more elaborate than a simple string atom
- Text<std::string> eventParamText = _doc.createTextNode(paramIter->second.atom);
-
- eventParamElem.setAttribute("id", paramIter->first);
- eventParamElem.appendChild(eventParamText);
- eventDataElem.appendChild(eventParamElem);
- paramIter++;
- }
- }
- if (event.namelist.size() > 0) {
- std::map<std::string, Data>::const_iterator namelistIter = event.namelist.begin();
- while(namelistIter != event.namelist.end()) {
- Element<std::string> eventNamelistElem = _doc.createElement("data");
- // this is simplified - Data might be more elaborate than a simple string atom
- Text<std::string> eventNamelistText = _doc.createTextNode(namelistIter->second.atom);
-
- eventNamelistElem.setAttribute("id", namelistIter->first);
- eventNamelistElem.appendChild(eventNamelistText);
- eventDataElem.appendChild(eventNamelistElem);
- namelistIter++;
- }
- }
- if (event.raw.size() > 0) {
- Element<std::string> eventRawElem = _doc.createElement("raw");
- Text<std::string> textNode = _doc.createTextNode(event.raw.c_str());
- eventRawElem.appendChild(textNode);
- eventElem.appendChild(eventRawElem);
- }
-
- if (event.content.size() > 0) {
- Text<std::string> textNode = _doc.createTextNode(spaceNormalize(event.content).c_str());
- eventDataElem.appendChild(textNode);
- }
- if (event.dom) {
- Node<std::string> importedNode = _doc.importNode(event.dom, true);
- eventDataElem.appendChild(importedNode);
- }
- if (event.data.array.size() == 1) {
- Text<std::string> textNode = _doc.createTextNode(event.data.array.front().atom.c_str());
- eventDataElem.appendChild(textNode);
- } else if (event.data.array.size() > 1) {
- std::list<uscxml::Data>::const_iterator ptr;
- unsigned int i;
-
- for( i = 0 , ptr = event.data.array.begin() ;
- ((i < event.data.array.size()) && (ptr != event.data.array.end()));
- i++ , ptr++ ) {
- Element<std::string> eventMESElem = _doc.createElement("data");
- Text<std::string> textNode = _doc.createTextNode(ptr->atom.c_str());
- std::stringstream ss;
- ss << i;
- eventMESElem.setAttribute("id", ss.str());
- eventMESElem.appendChild(textNode);
- eventDataElem.appendChild(eventMESElem);
- }
- }
-
- eventElem.appendChild(eventDataElem);
- eventNodeSet.push_back(eventElem);
-
- // do we need to replace an existing event?
- Node<std::string> oldEventElem = _datamodel.getFirstChild();
- while(oldEventElem) {
- if (oldEventElem.getNodeType() == Node_base::ELEMENT_NODE) {
- if (HAS_ATTR_CAST(oldEventElem, "id") && iequals(ATTR_CAST(oldEventElem, "id"), "_event"))
- break;
- }
- oldEventElem = oldEventElem.getNextSibling();
- }
-
- if (oldEventElem) {
- _datamodel.replaceChild(eventElem, oldEventElem);
- } else {
- _datamodel.appendChild(eventElem);
- }
- _varResolver.setVariable("_event", eventNodeSet);
-}
-
-Data XPathDataModel::getStringAsData(const std::string& content) {
- Data data;
- XPathValue<std::string> result = _xpath.evaluate_expr(content, _doc);
-
- std::stringstream ss;
-
- switch (result.type()) {
- case ANY:
- break;
- case Arabica::XPath::BOOL:
- ss << result.asBool();
- break;
- case NUMBER:
- ss << result.asNumber();
- break;
- case STRING:
- ss << result.asString();
- break;
- case NODE_SET:
- NodeSet<std::string> ns = result.asNodeSet();
- for (size_t i = 0; i < ns.size(); i++) {
- ss.str("");
- ss << i;
- std::string idx = ss.str();
- ss.str("");
- ss << ns[i];
- data.compound[idx] = Data(ss.str(), Data::INTERPRETED);
- }
- data.type = Data::INTERPRETED;
- return data;
- break;
- }
-
- data.atom = ss.str();
- data.type = Data::VERBATIM;
- return data;
-}
-
-bool XPathDataModel::validate(const std::string& location, const std::string& schema) {
- return true;
-}
-
-bool XPathDataModel::isLocation(const std::string& expr) {
- return true;
-}
-
-uint32_t XPathDataModel::getLength(const std::string& expr) {
-// std::cout << _datamodel << std::endl;
- XPathValue<std::string> result = _xpath.evaluate_expr(expr, _doc);
- switch(result.type()) {
- case NUMBER:
- return result.asNumber();
- break;
- case NODE_SET:
- return result.asNodeSet().size();
- break;
- default:
- ERROR_EXECUTION_THROW("'" + expr + "' does not evaluate to an array.");
- }
- return 0;
-}
-
-void XPathDataModel::setForeach(const std::string& item,
- const std::string& array,
- const std::string& index,
- uint32_t iteration) {
-
- XPathValue<std::string> arrayResult = _xpath.evaluate_expr(array, _doc);
- assert(arrayResult.type() == NODE_SET);
-
-#if 0
- std::cout << "Array Size: " << arrayResult.asNodeSet().size() << std::endl;
- for (size_t i = 0; i < arrayResult.asNodeSet().size(); i++) {
- std::cout << arrayResult.asNodeSet()[i] << std::endl;
- }
-#endif
-
- assert(arrayResult.asNodeSet().size() >= iteration);
-
-
- NodeSet<std::string> arrayNodeSet;
- arrayNodeSet.push_back(arrayResult.asNodeSet()[iteration]);
-
- if (!isDeclared(item)) {
- if (!isValidIdentifier(item))
- ERROR_EXECUTION_THROW("Expression '" + item + "' not a valid identifier.");
- Element<std::string> container = _doc.createElement("data");
- container.setAttribute("id", item);
- container.appendChild(arrayResult.asNodeSet()[iteration].cloneNode(true));
- _datamodel.appendChild(container);
- _varResolver.setVariable(item, arrayNodeSet);
- }
- XPathValue<std::string> itemResult = _varResolver.resolveVariable("", item);
- assign(itemResult, arrayNodeSet, Element<std::string>());
-
- if (index.length() > 0) {
- NodeSet<std::string> indexNodeSet;
- Text<std::string> indexElem = _doc.createTextNode(toStr(iteration));
- indexNodeSet.push_back(indexElem);
-
- if (!isDeclared(index)) {
- Element<std::string> container = _doc.createElement("data");
- container.setAttribute("id", index);
- container.appendChild(indexElem);
- _datamodel.appendChild(container);
-
- NodeSet<std::string> indexVarNodeSet;
- indexVarNodeSet.push_back(container);
- _varResolver.setVariable(index, indexVarNodeSet);
- }
- XPathValue<std::string> indexResult = _varResolver.resolveVariable("", index);
- assign(indexResult, indexNodeSet, Element<std::string>());
- }
-
-
-#if 0
- std::cout << _datamodel << std::endl << std::endl;
- std::cout << "Index: " << indexResult.asNodeSet().size() << std::endl;
- for (size_t i = 0; i < indexResult.asNodeSet().size(); i++) {
- std::cout << indexResult.asNodeSet()[i] << std::endl;
- }
- std::cout << std::endl;
-#endif
-
-
-}
-
-bool XPathDataModel::isValidIdentifier(const std::string& identifier) {
- if(boost::starts_with(identifier, "."))
- return false;
-
- return true;
-}
-
-
-void XPathDataModel::eval(const Arabica::DOM::Element<std::string>& scriptElem,
- const std::string& expr) {
- XPathValue<std::string> result = _xpath.evaluate_expr(expr, _doc);
-}
-
-bool XPathDataModel::isDeclared(const std::string& expr) {
- return true;
- try {
- return _varResolver.isDeclared(expr) || evalAsBool(expr);
- } catch(...) {
- return false;
- }
-}
-
-bool XPathDataModel::evalAsBool(const std::string& expr) {
- return evalAsBool(Arabica::DOM::Element<std::string>(), expr);
-}
-
-bool XPathDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) {
-// std::cout << std::endl << evalAsString(expr);
- XPathValue<std::string> result;
- try {
- result = _xpath.evaluate_expr(expr, _doc);
- } catch(SyntaxException e) {
- ERROR_EXECUTION_THROW(e.what());
- } catch(std::runtime_error e) {
- ERROR_EXECUTION_THROW(e.what());
- }
- return result.asBool();
-}
-
-std::string XPathDataModel::evalAsString(const std::string& expr) {
-
- XPathValue<std::string> result;
- try {
- result = _xpath.evaluate_expr(expr, _doc);
- } catch(SyntaxException e) {
- ERROR_EXECUTION_THROW(e.what());
- } catch(std::runtime_error e) {
- ERROR_EXECUTION_THROW(e.what());
- }
- switch (result.type()) {
- case STRING:
- return result.asString();
- break;
- case Arabica::XPath::BOOL: // MSVC croaks with ambiguous symbol without qualified name
- return (result.asBool() ? "true" : "false");
- break;
- case NUMBER:
- return toStr(result.asNumber());
- break;
- case NODE_SET: {
- NodeSet<std::string> nodeSet = result.asNodeSet();
- std::stringstream ss;
- for (size_t i = 0; i < nodeSet.size(); i++) {
- ss << nodeSet[i];
- if (nodeSet[i].getNodeType() != Node_base::TEXT_NODE) {
- ss << std::endl;
- }
- }
- return ss.str();
- break;
- }
- case ANY:
- ERROR_EXECUTION_THROW("Type ANY not supported to evaluate as string");
- break;
- }
- return "undefined";
-}
-
-double XPathDataModel::evalAsNumber(const std::string& expr) {
- XPathValue<std::string> result = _xpath.evaluate_expr(expr, _doc);
- return result.asNumber();
-}
-
-void XPathDataModel::assign(const Element<std::string>& assignElem,
- const Node<std::string>& node,
- const std::string& content) {
- std::string location;
- if (HAS_ATTR(assignElem, "id")) {
- location = ATTR(assignElem, "id");
- } else if (HAS_ATTR(assignElem, "location")) {
- location = ATTR(assignElem, "location");
- }
-
- // test 326ff
- XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc);
-#ifdef VERBOSE
- LOG(INFO) << "Key XPath : " << key.asString();
-#endif
-#if 0
- if (key.type() == NODE_SET) {
- try {
- for (size_t i = 0; i < key.asNodeSet().size(); i++) {
- Node<std::string> node = key.asNodeSet()[i];
- if (node == _varResolver.resolveVariable("", "_ioprocessors").asNodeSet()[0])
- ERROR_EXECUTION_THROW("Cannot assign _ioProcessors");
- if (node == _varResolver.resolveVariable("", "_sessionid").asNodeSet()[0])
- ERROR_EXECUTION_THROW("Cannot assign _sessionid");
- if (node == _varResolver.resolveVariable("", "_name").asNodeSet()[0])
- ERROR_EXECUTION_THROW("Cannot assign _name");
- if (node == _varResolver.resolveVariable("", "_event").asNodeSet()[0])
- ERROR_EXECUTION_THROW("Cannot assign _event");
- }
- } catch (Event e) {}
- }
-#endif
- NodeSet<std::string> nodeSet;
- if (node) {
- Node<std::string> data = node;
- while (data) {
- // do not add empty text as a node
- if (data.getNodeType() == Node_base::TEXT_NODE) {
- std::string trimmed = data.getNodeValue();
- boost::trim(trimmed);
- if (trimmed.length() == 0) {
- data = data.getNextSibling();
- continue;
- }
- }
- nodeSet.push_back(data);
- data = data.getNextSibling();
- }
- assign(key, nodeSet, assignElem);
- } else if (content.length() > 0) {
- Text<std::string> textNode = _doc.createTextNode(spaceNormalize(content));
- nodeSet.push_back(textNode);
- assign(key, nodeSet, assignElem);
- } else if (HAS_ATTR(assignElem, "expr")) {
- XPathValue<std::string> value = _xpath.evaluate_expr(ATTR(assignElem, "expr"), _doc);
-#ifdef VERBOSE
- LOG(INFO) << "Value XPath : " << value.asString();
-#endif
- assign(key, value, assignElem);
- } else {
- LOG(ERROR) << "assign element has no content";
- }
-
-// std::cout << _datamodel << std::endl;
-}
-
-void XPathDataModel::assign(const std::string& location, const Data& data) {
- XPathValue<std::string> locationResult = _xpath.evaluate_expr(location, _doc);
- NodeSet<std::string> dataNodeSet = dataToNodeSet(data);
- assign(locationResult, dataNodeSet, Element<std::string>());
-// std::cout << _datamodel << std::endl;
-}
-
-NodeSet<std::string> XPathDataModel::dataToNodeSet(const Data& data) {
- NodeSet<std::string> dataNodeSet;
- if (data.atom.length() > 0) {
- dataNodeSet.push_back(_doc.createTextNode(data.atom));
- }
- return dataNodeSet;
-}
-
-void XPathDataModel::init(const Element<std::string>& dataElem,
- const Node<std::string>& node,
- const std::string& content) {
- std::string location;
- if (HAS_ATTR(dataElem, "id")) {
- location = ATTR(dataElem, "id");
- } else if (HAS_ATTR(dataElem, "location")) {
- location = ATTR(dataElem, "location");
- }
-
- NodeSet<std::string> nodeSet;
- if (node || (content.length() > 0)) {
- _datamodel.appendChild(_doc.importNode(dataElem, true));
- nodeSet.push_back(dataElem);
- } else if (HAS_ATTR(dataElem, "expr")) {
- try {
- Element<std::string> container = _doc.createElement("data");
- container.setAttribute("id", location);
- XPathValue<std::string> expr = _xpath.evaluate_expr(ATTR(dataElem, "expr"), _doc);
- switch (expr.type()) {
- case NODE_SET: {
- for (size_t i = 0; i < expr.asNodeSet().size(); i++) {
- container.appendChild(expr.asNodeSet()[i].cloneNode(true));
- nodeSet.push_back(expr.asNodeSet()[i].cloneNode(true));
- }
- break;
- }
- case STRING:
- container.appendChild(_doc.createTextNode(expr.asString()));
- nodeSet.push_back(_doc.createTextNode(expr.asString()));
- break;
- case NUMBER: {
- container.appendChild(_doc.createTextNode(toStr(expr.asNumber())));
- nodeSet.push_back(_doc.createTextNode(toStr(expr.asNumber())));
- break;
- }
- case Arabica::XPath::BOOL:
- case ANY:
- ERROR_EXECUTION_THROW("expr evaluates to type ANY");
- }
- _datamodel.appendChild(container);
- } catch (SyntaxException e) {
- ERROR_EXECUTION_THROW(e.what());
- }
- } else {
- LOG(ERROR) << "data element has no content";
- }
-
- _varResolver.setVariable(location, nodeSet);
-}
-
-void XPathDataModel::init(const std::string& location, const Data& data) {
- NodeSet<std::string> nodeSet;
- _varResolver.setVariable(location, nodeSet);
-}
-
-
-void XPathDataModel::assign(const XPathValue<std::string>& key,
- const XPathValue<std::string>& value,
- const Element<std::string>& assignElem) {
- switch (key.type()) {
- case NODE_SET:
- if (key.asNodeSet().size() == 0) {
- ERROR_EXECUTION_THROW("key for assign is empty nodeset");
- }
- switch (value.type()) {
- case STRING:
- assign(key.asNodeSet(), value.asString(), assignElem);
- break;
- case Arabica::XPath::BOOL:
- assign(key.asNodeSet(), value.asBool(), assignElem);
- break;
- case NUMBER:
- assign(key.asNodeSet(), value.asNumber(), assignElem);
- break;
- case NODE_SET:
- assign(key.asNodeSet(), value.asNodeSet(), assignElem);
- break;
- case ANY:
- ERROR_EXECUTION_THROW("Type ANY as key for assign not supported");
- }
- break;
- case STRING:
- case Arabica::XPath::BOOL:
- case NUMBER:
- case ANY:
- ERROR_EXECUTION_THROW("Type ANY as key for assign not supported")
- break;
- }
-}
-
-void XPathDataModel::assign(const XPathValue<std::string>& key,
- const NodeSet<std::string>& value,
- const Element<std::string>& assignElem) {
- if (value.size() == 0 || !value[0])
- return;
- switch (key.type()) {
- case NODE_SET: {
- assign(key.asNodeSet(), value, assignElem);
- break;
- }
- case STRING:
- case Arabica::XPath::BOOL:
- case NUMBER:
- case ANY:
- ERROR_EXECUTION_THROW("Type ANY as key for assign not supported")
- }
-}
-
-void XPathDataModel::assign(const NodeSet<std::string>& key,
- const std::string& value,
- const Element<std::string>& assignElem) {
- if (key.size() == 0)
- return;
- for (size_t i = 0; i < key.size(); i++) {
- Node<std::string> node = key[i];
- switch (node.getNodeType()) {
- case Node_base::ATTRIBUTE_NODE: {
- Attr<std::string> attr(node);
- attr.setValue(value);
- break;
- }
- case Node_base::TEXT_NODE: {
- Text<std::string> text(node);
- text.setNodeValue(value);
- break;
- }
- case Node_base::ELEMENT_NODE: {
- Element<std::string> element(node);
- if (HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "addattribute")) {
- // addattribute: Add an attribute with the name specified by 'attr'
- // and value specified by 'expr' to the node specified by 'location'.
- if (!HAS_ATTR(assignElem, "attr"))
- ERROR_EXECUTION_THROW("Assign element is missing 'attr'");
- element.setAttribute(ATTR(assignElem, "attr"), value);
- } else {
- /// test 547
- while(element.hasChildNodes())
- element.removeChild(element.getChildNodes().item(0));
- Text<std::string> text = _doc.createTextNode(value);
- element.appendChild(text);
- }
- break;
- }
- default:
- ERROR_EXECUTION_THROW("Unsupported node type with assign");
- break;
- }
- }
-}
-
-void XPathDataModel::assign(const NodeSet<std::string>& key,
- const double value,
- const Element<std::string>& assignElem) {
- assign(key, toStr(value), assignElem);
-}
-
-void XPathDataModel::assign(const NodeSet<std::string>& key,
- const bool value,
- const Element<std::string>& assignElem) {
-}
-
-void XPathDataModel::assign(const NodeSet<std::string>& key,
- const NodeSet<std::string>& value,
- const Element<std::string>& assignElem) {
- if (key.size() == 0)
- return;
- if (value.size() == 0 || !value[0])
- return;
-
- for (size_t i = 0; i < key.size(); i++) {
- switch (key[i].getNodeType())
- case Node_base::ELEMENT_NODE: {
- assign(Element<std::string>(key[i]), value, assignElem);
- break;
- default:
-// std::cout << key[i].getNodeType() << std::endl;
- ERROR_EXECUTION_THROW("Unsupported node type for assign");
- break;
- }
- }
-}
-
-void XPathDataModel::assign(const Element<std::string>& key,
- const NodeSet<std::string>& value,
- const Element<std::string>& assignElem) {
- Element<std::string> element(key);
- if (value.size() == 0 || !value[0])
- return;
-
- if (false) {
- } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "firstchild")) {
- // firstchild: Insert the value specified by 'expr' before all of the children at 'location'.
- for (size_t i = value.size(); i; i--) {
- Node<std::string> importedNode = (value[i-1].getOwnerDocument() == _doc ? value[i-1].cloneNode(true) : _doc.importNode(value[i-1], true));
- element.insertBefore(importedNode, element.getFirstChild());
- }
- } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "lastchild")) {
- // lastchild: Insert the value specified by 'expr' after all of the children at 'location'.
- for (size_t i = 0; i < value.size(); i++) {
- Node<std::string> importedNode = (value[i].getOwnerDocument() == _doc ? value[i].cloneNode(true) : _doc.importNode(value[i], true));
- element.appendChild(importedNode);
- }
- } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "previoussibling")) {
- // previoussibling: Insert the value specified by 'expr' before the
- // node specified by 'location', keeping the same parent.
- Node<std::string> parent = element.getParentNode();
- if (!parent)
- ERROR_EXECUTION_THROW("Node has no parent");
- for (size_t i = 0; i < value.size(); i++) {
- Node<std::string> importedNode = (value[i].getOwnerDocument() == _doc ? value[i].cloneNode(true) : _doc.importNode(value[i], true));
- parent.insertBefore(importedNode, element);
- }
- } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "nextsibling")) {
- // nextsibling: Insert the value specified by 'expr' after the node
- // specified by 'location', keeping the same parent.
- Node<std::string> parent = element.getParentNode();
- if (!parent)
- ERROR_EXECUTION_THROW("Node has no parent");
- for (size_t i = value.size(); i; i--) {
- Node<std::string> importedNode = (value[i-1].getOwnerDocument() == _doc ? value[i-1].cloneNode(true) : _doc.importNode(value[i-1], true));
- Node<std::string> nextSibling = element.getNextSibling();
- if (nextSibling) {
- parent.insertBefore(importedNode, element.getNextSibling());
- } else {
- parent.appendChild(importedNode);
- }
- }
- } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "replace")) {
- // replace: Replace the node specified by 'location' by the value specified by 'expr'.
- Node<std::string> parent = element.getParentNode();
- if (!parent)
- ERROR_EXECUTION_THROW("Node has no parent");
- if (value.size() != 1)
- ERROR_EXECUTION_THROW("Value not singular");
- Node<std::string> importedNode = (value[0].getOwnerDocument() == _doc ? value[0].cloneNode(true) : _doc.importNode(value[0], true));
- parent.replaceChild(importedNode, element);
- } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "delete")) {
- // delete: Delete the node specified by 'location'. ('expr' is ignored.).
- Node<std::string> parent = element.getParentNode();
- if (!parent)
- ERROR_EXECUTION_THROW("Node has no parent");
- parent.removeChild(element);
- } else {
- // replacechildren: Replace all the children at 'location' with the value specified by 'expr'.
- while(element.hasChildNodes())
- element.removeChild(element.getChildNodes().item(0));
- for (size_t i = 0; i < value.size(); i++) {
- Node<std::string> importedNode = element.getOwnerDocument().importNode(value[i], true);
- element.appendChild(importedNode);
- }
- }
-}
-
-XPathValue<std::string>
-NodeSetVariableResolver::resolveVariable(const std::string& namepaceUri,
- const std::string& name) const {
- std::map<std::string, NodeSet<std::string> >::const_iterator n = _variables.find(name);
- if(n == _variables.end()) {
- ERROR_EXECUTION_THROW("No variable named '" + name + "'");
- }
-#if VERBOSE
- std::cout << std::endl << "Getting " << name << ":" << std::endl;
- for (size_t i = 0; i < n->second.size(); i++) {
- std::cout << n->second[i].getNodeType() << " | " << n->second[i] << std::endl;
- }
- std::cout << std::endl;
-#endif
- return XPathValue<std::string>(new NodeSetValue<std::string>(n->second));
-}
-
-void NodeSetVariableResolver::setVariable(const std::string& name, const NodeSet<std::string>& value) {
-#if VERBOSE
- std::cout << std::endl << "Setting " << name << ":" << std::endl;
- for (size_t i = 0; i < value.size(); i++) {
- std::cout << value[i].getNodeType() << " | " << value[i] << std::endl;
- }
- std::cout << std::endl;
-#endif
- _variables[name] = value;
-#if 0
- std::map<std::string, Arabica::XPath::NodeSet<std::string> >::iterator varIter = _variables.begin();
- while (varIter != _variables.end()) {
- std::cout << varIter->first << ":" << std::endl;
- for (size_t i = 0; i < varIter->second.size(); i++) {
- std::cout << varIter->second[i].getNodeType() << " | " << varIter->second[i] << std::endl;
- }
- varIter++;
- }
-#endif
-}
-
-bool NodeSetVariableResolver::isDeclared(const std::string& name) {
-#if 0
- std::map<std::string, Arabica::XPath::NodeSet<std::string> >::iterator varIter = _variables.begin();
- while (varIter != _variables.end()) {
- std::cout << varIter->first << std::endl;
- varIter++;
- }
-#endif
- return _variables.find(name) != _variables.end();
-}
-
-XPathFunction<std::string>*
-XPathFunctionResolver::resolveFunction(const std::string& namespace_uri,
- const std::string& name,
- const std::vector<XPathExpression<std::string> >& argExprs) const {
- if (iequals(name, "in")) {
- return new XPathFunctionIn(1, -1, argExprs, _interpreter);
- }
- return _xpathFuncRes.resolveFunction(namespace_uri, name, argExprs);
-}
-
-std::vector<std::pair<std::string, std::string> > XPathFunctionResolver::validNames() const {
- std::vector<std::pair<std::string, std::string> > names = _xpathFuncRes.validNames();
- names.push_back(std::make_pair("", "In"));
- return names;
-}
-
-bool XPathFunctionIn::doEvaluate(const Node<std::string>& context,
- const ExecutionContext<std::string>& executionContext) const {
- for (size_t i = 0; i < argCount(); i++) {
- XPathValue<std::string> stateName = arg(i, context, executionContext);
- if (stateName.type() == STRING) {
- if (_interpreter->isInState(stateName.asString())) {
- continue;
- }
- }
- return false;
- }
- return true;
-}
-
-}