summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-12 11:57:08 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-12 11:57:08 (GMT)
commitba050afaaad699e60ca657b311d5c34d038bb89c (patch)
treed4c79e30631c63e8557c6ec893a70dda46aa6cd5
parent45ab2909e17f7e0348ccfe4179f23a897a2fd305 (diff)
downloaduscxml-ba050afaaad699e60ca657b311d5c34d038bb89c.zip
uscxml-ba050afaaad699e60ca657b311d5c34d038bb89c.tar.gz
uscxml-ba050afaaad699e60ca657b311d5c34d038bb89c.tar.bz2
Refactoring for other datamodels
-rw-r--r--contrib/ctest/CTestCustom.ctest.in9
-rw-r--r--src/bindings/swig/php/uscxmlNativePHP.php58
-rw-r--r--src/uscxml/Factory.h78
-rw-r--r--src/uscxml/Interpreter.cpp287
-rw-r--r--src/uscxml/Interpreter.h25
-rw-r--r--src/uscxml/Message.cpp18
-rw-r--r--src/uscxml/interpreter/InterpreterDraft6.cpp6
-rw-r--r--src/uscxml/interpreter/InterpreterDraft7.cpp55
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp132
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h40
-rw-r--r--src/uscxml/plugins/datamodel/null/NULLDataModel.cpp16
-rw-r--r--src/uscxml/plugins/datamodel/null/NULLDataModel.h30
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp37
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h27
-rw-r--r--src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp443
-rw-r--r--src/uscxml/plugins/datamodel/xpath/XPathDataModel.h82
-rw-r--r--src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp4
-rw-r--r--test/samples/w3c/ecma/test530.scxml4
-rw-r--r--test/src/test-arabica-xpath.cpp196
19 files changed, 820 insertions, 727 deletions
diff --git a/contrib/ctest/CTestCustom.ctest.in b/contrib/ctest/CTestCustom.ctest.in
index fd93ab6..d90a6b6 100644
--- a/contrib/ctest/CTestCustom.ctest.in
+++ b/contrib/ctest/CTestCustom.ctest.in
@@ -8,15 +8,6 @@
# skip xpath datamodel tests
set(CTEST_CUSTOM_TESTS_IGNORE
- "test539.scxml"
- "test540.scxml"
- "test542.scxml"
- "test544.scxml"
- "test546.scxml"
- "test547.scxml"
- "test555.scxml"
- "test568.scxml"
-
"test178.scxml"
"test230.scxml"
"test250.scxml"
diff --git a/src/bindings/swig/php/uscxmlNativePHP.php b/src/bindings/swig/php/uscxmlNativePHP.php
index 89cad82..c15f979 100644
--- a/src/bindings/swig/php/uscxmlNativePHP.php
+++ b/src/bindings/swig/php/uscxmlNativePHP.php
@@ -32,56 +32,6 @@ abstract class uscxmlNativePHP {
const CAN_BASIC_HTTP = 1;
const CAN_GENERIC_HTTP = 2;
-
- const ANY = 0;
-
- const BOOL = BOOL;
-
- const NUMBER = NUMBER;
-
- const STRING = STRING;
-
- const NODE_SET = NODE_SET;
-
- static function NaN_get() {
- return NaN_get();
- }
-
- static function Zero_get() {
- return Zero_get();
- }
-
- static function Negative_Zero_get() {
- return Negative_Zero_get();
- }
-
- static function Infinity_get() {
- return Infinity_get();
- }
-
- static function Negative_Infinity_get() {
- return Negative_Infinity_get();
- }
-
- static function isNaN($value) {
- return isNaN($value);
- }
-
- static function isInfinity($value) {
- return isInfinity($value);
- }
-
- static function isNegativeInfinity($value) {
- return isNegativeInfinity($value);
- }
-
- static function isInfinite($value) {
- return isInfinite($value);
- }
-
- static function roundNumber($value) {
- return roundNumber($value);
- }
}
/* PHP Proxy Classes */
@@ -700,7 +650,13 @@ class Interpreter {
}
function getConfiguration() {
- return Interpreter_getConfiguration($this->_cPtr);
+ $r=Interpreter_getConfiguration($this->_cPtr);
+ if (is_resource($r)) {
+ $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));
+ if (class_exists($c)) return new $c($r);
+ return new ParamList($r);
+ }
+ return $r;
}
function setConfiguration($states) {
diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h
index 540cf61..e21fe72 100644
--- a/src/uscxml/Factory.h
+++ b/src/uscxml/Factory.h
@@ -240,32 +240,21 @@ public:
virtual void pushContext() = 0;
virtual void popContext() = 0;
- virtual bool supportsJSON() { return false; }
-
virtual void eval(const std::string& expr) = 0;
virtual std::string evalAsString(const std::string& expr) = 0;
virtual bool evalAsBool(const std::string& expr) = 0;
+
virtual bool isDeclared(const std::string& expr) = 0;
- virtual void assign(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& assignElem) = 0;
- virtual void assign(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& assignElem) = 0;
- virtual void assign(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& assignElem) = 0;
-
- virtual void init(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& dataElem) = 0;
- virtual void init(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& dataElem) = 0;
- virtual void init(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& dataElem) = 0;
+ virtual void assign(const Arabica::DOM::Element<std::string>& assignElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content) = 0;
+ virtual void assign(const std::string& location, const Data& data) = 0;
+
+ virtual void init(const Arabica::DOM::Element<std::string>& dataElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content) = 0;
+ virtual void init(const std::string& location, const Data& data) = 0;
protected:
InterpreterImpl* _interpreter;
@@ -305,18 +294,12 @@ public:
return _impl->getStringAsData(content);
}
- virtual uint32_t getLength(const std::string& expr) {
- return _impl->getLength(expr);
- }
virtual void pushContext() {
return _impl->pushContext();
}
virtual void popContext() {
return _impl->popContext();
}
- virtual bool supportsJSON() {
- return _impl->supportsJSON();
- }
virtual void eval(const std::string& expr) {
return _impl->eval(expr);
@@ -327,37 +310,26 @@ public:
virtual bool evalAsBool(const std::string& expr) {
return _impl->evalAsBool(expr);
}
-
- virtual void assign(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& assignElem) {
- return _impl->assign(location, doc, assignElem);
+ virtual uint32_t getLength(const std::string& expr) {
+ return _impl->getLength(expr);
}
- virtual void assign(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& assignElem) {
- return _impl->assign(location, expr, assignElem);
+
+ virtual void assign(const Arabica::DOM::Element<std::string>& assignElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content) {
+ return _impl->assign(assignElem, doc, content);
}
- virtual void assign(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& assignElem) {
- return _impl->assign(location, data, assignElem);
+ virtual void assign(const std::string& location, const Data& data) {
+ return _impl->assign(location, data);
}
- virtual void init(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& dataElem) {
- return _impl->init(location, doc, dataElem);
- }
- virtual void init(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& dataElem) {
- return _impl->init(location, expr, dataElem);
+ virtual void init(const Arabica::DOM::Element<std::string>& dataElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content) {
+ return _impl->init(dataElem, doc, content);
}
- virtual void init(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& dataElem) {
- return _impl->init(location, data, dataElem);
+ virtual void init(const std::string& location, const Data& data) {
+ return _impl->init(location, data);
}
virtual bool isDeclared(const std::string& expr) {
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index a78d4a0..7fe5cc1 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -319,15 +319,10 @@ void InterpreterImpl::initializeData(const Element<std::string>& data) {
return;
}
- if (!HAS_ATTR(data, "id")) {
- LOG(ERROR) << "Data element has no id!";
- return;
- }
-
- /// test 240 - initialize from invoke request
+ /// test 226/240 - initialize from invoke request
if (_invokeReq.params.find(ATTR(data, "id")) != _invokeReq.params.end()) {
try {
- _dataModel.init(ATTR(data, "id"), _invokeReq.params.find(ATTR(data, "id"))->second, data);
+ _dataModel.init(ATTR(data, "id"), _invokeReq.params.find(ATTR(data, "id"))->second);
} catch (Event e) {
LOG(ERROR) << "Syntax error when initializing data from parameters:" << std::endl << e << std::endl;
receiveInternal(e);
@@ -336,7 +331,7 @@ void InterpreterImpl::initializeData(const Element<std::string>& data) {
}
if (_invokeReq.namelist.find(ATTR(data, "id")) != _invokeReq.namelist.end()) {
try {
- _dataModel.init(ATTR(data, "id"), _invokeReq.namelist.find(ATTR(data, "id"))->second, data);
+ _dataModel.init(ATTR(data, "id"), _invokeReq.namelist.find(ATTR(data, "id"))->second);
} catch (Event e) {
LOG(ERROR) << "Syntax error when initializing data from namelist:" << std::endl << e << std::endl;
receiveInternal(e);
@@ -345,113 +340,12 @@ void InterpreterImpl::initializeData(const Element<std::string>& data) {
}
try {
- std::string contentToProcess;
- if (HAS_ATTR(data, "expr")) {
- // expression given directly
- std::string value = ATTR(data, "expr");
- try {
- _dataModel.init(ATTR(data, "id"), value, data);
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in data element:" << std::endl << e << std::endl;
- /// test 277
- /// todo: if the identifier is invalid we'll raise to error events
- receiveInternal(e);
- _dataModel.init(ATTR(data, "id"), "undefined", data);
- }
- return;
- }
-
- if (HAS_ATTR(data, "src")) {
- // fetch us some string and proess below
- URL srcURL(ATTR(data, "src"));
- if (!srcURL.isAbsolute())
- toAbsoluteURI(srcURL);
-
- std::stringstream ss;
- if (_cachedURLs.find(srcURL.asString()) != _cachedURLs.end()) {
- ss << _cachedURLs[srcURL.asString()];
- } else {
- ss << srcURL;
- _cachedURLs[srcURL.asString()] = srcURL;
- }
- contentToProcess = ss.str();
-
- // try to parse as XML
- std::stringstream* xmlStr = new std::stringstream();
- (*xmlStr) << contentToProcess;
- std::auto_ptr<std::istream> ssPtr(xmlStr);
- Arabica::SAX::InputSource<std::string> inputSource;
- inputSource.setByteStream(ssPtr);
- Arabica::SAX2DOM::Parser<std::string> parser;
- if(parser.parse(inputSource) && parser.getDocument()) {
- try {
- _dataModel.init(ATTR(data, "id"), parser.getDocument(), data);
- return;
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in data element:" << std::endl << e << std::endl;
- receiveInternal(e);
- _dataModel.init(ATTR(data, "id"), "undefined", data);
- }
- return;
- }
- } else if (data.hasChildNodes()) {
- bool presentAsDom = false;
- Node<std::string> contentChild = data.getFirstChild();
- while(contentChild) {
- if (contentChild.getNodeType() == Node_base::TEXT_NODE) {
- std::string trimmed = contentChild.getNodeValue();
- boost::trim(trimmed);
- if (trimmed.length() > 0)
- break;
- }
- if (contentChild.getNodeType() == Node_base::ELEMENT_NODE) {
- presentAsDom = true;
- break;
- }
- contentChild = contentChild.getNextSibling();
- }
-
- if (contentChild && presentAsDom) {
- Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
- Document<std::string> dom = domFactory.createDocument(contentChild.getNamespaceURI(), "", 0);
- Node<std::string> newNode = dom.importNode(contentChild, true);
- dom.appendChild(newNode);
- _dataModel.init(ATTR(data, "id"), dom, data);
- return;
- } else if (contentChild) {
- // get first child and process below
- contentToProcess = contentChild.getNodeValue();
- } else {
- LOG(ERROR) << "content element has no text or element children.";
- }
- }
- if (contentToProcess.length() > 0) {
- /// try to interpret as JSON
- try {
- _dataModel.init(ATTR(data, "id"), contentToProcess, data);
- } catch(Event e) {
- /// create space normalized string if that failed
- /// test 558
- std::istringstream iss(contentToProcess);
- std::stringstream spaceNormalized;
- std::string seperator;
- do {
- std::string token;
- iss >> token;
- if (token.length() > 0) {
- spaceNormalized << seperator << token;
- seperator = " ";
- }
- } while (iss);
- _dataModel.init(ATTR(data, "id"), Data(spaceNormalized.str(), Data::VERBATIM), data);
- }
- } else {
- _dataModel.init(ATTR(data, "id"), "undefined", data);
- }
-
+ Arabica::DOM::Document<std::string> dom;
+ std::string text;
+ processDOMorText(data, dom, text);
+ _dataModel.init(data, dom, text);
} catch (Event e) {
- LOG(ERROR) << "Syntax error in data element:" << std::endl << e << std::endl;
- /// test 487
+ LOG(ERROR) << "Syntax error when initializing data:" << std::endl << e << std::endl;
receiveInternal(e);
}
}
@@ -518,12 +412,12 @@ void InterpreterImpl::normalize(Arabica::DOM::Element<std::string>& scxml) {
}
void InterpreterImpl::receiveInternal(const Event& event) {
-// std::cout << "receiveInternal: " << event.name << std::endl;
+ std::cout << _name << " receiveInternal: " << event.name << std::endl;
_internalQueue.push_back(event);
}
void InterpreterImpl::receive(const Event& event, bool toFront) {
-// std::cout << "receive: " << event.name << std::endl;
+ std::cout << _name << " receive: " << event.name << std::endl;
if (toFront) {
_externalQueue.push_front(event);
} else {
@@ -547,8 +441,18 @@ void InterpreterImpl::internalDoneSend(const Arabica::DOM::Node<std::string>& st
Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", doneDatas[0]);
if (contents.size() > 1)
LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
- if (contents.size() > 0)
- processContentElement(contents[0], event.dom, event.content, event.data);
+ if (contents.size() > 0) {
+ std::string expr;
+ processContentElement(contents[0], event.dom, event.content, expr);
+ if (expr.length() > 0 && _dataModel) {
+ try {
+ event.content =_dataModel.evalAsString(expr);
+ } catch (Event e) {
+ e.name = "error.execution";
+ receiveInternal(e);
+ }
+ }
+ }
}
event.name = "done.state." + ATTR(stateElem.getParentNode(), "id"); // parent?!
@@ -559,13 +463,22 @@ void InterpreterImpl::internalDoneSend(const Arabica::DOM::Node<std::string>& st
void InterpreterImpl::processContentElement(const Arabica::DOM::Node<std::string>& content,
Arabica::DOM::Document<std::string>& dom,
std::string& text,
- Data& data) {
+ std::string& expr) {
+ if (HAS_ATTR(content, "expr")) {
+ expr = ATTR(content, "expr");
+ } else if (content.hasChildNodes()) {
+ processDOMorText(content, dom, text);
+ } else {
+ LOG(ERROR) << "content element does not specify any content.";
+ }
+
+#if 0
try {
std::string contentToProcess;
if (HAS_ATTR(content, "expr")) {
if (_dataModel) {
/// this is out of spec
- contentToProcess = _dataModel.evalAsString(ATTR(content, "expr"));
+ contentToProcess = ATTR(content, "expr");
// sendReq.data.atom = contentValue;
// sendReq.data.type = Data::VERBATIM;
} else {
@@ -629,6 +542,75 @@ void InterpreterImpl::processContentElement(const Arabica::DOM::Node<std::string
e.name = "error.execution";
receiveInternal(e);
}
+#endif
+}
+
+void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& node,
+ Arabica::DOM::Document<std::string>& dom,
+ std::string& text) {
+ // do we need to download?
+ if (HAS_ATTR(node, "src") ||
+ (HAS_ATTR(node, "srcexpr") && _dataModel)) {
+ std::stringstream srcContent;
+ URL sourceURL(HAS_ATTR(node, "srcexpr") ? _dataModel.evalAsString(ATTR(node, "srcexpr")) : ATTR(node, "src"));
+ if (!toAbsoluteURI(sourceURL)) {
+ LOG(ERROR) << LOCALNAME(node) << " element has relative src or srcexpr URI with no baseURI set.";
+ return;
+ }
+ if (_cachedURLs.find(sourceURL.asString()) != _cachedURLs.end()) {
+ srcContent << _cachedURLs[sourceURL.asString()];
+ } else {
+ srcContent << sourceURL;
+ if (sourceURL.downloadFailed()) {
+ LOG(ERROR) << LOCALNAME(node) << " source cannot be downloaded";
+ return;
+ }
+ _cachedURLs[sourceURL.asString()] = sourceURL;
+ }
+ if (srcContent.str().length() > 0) {
+ // try to parse as XML
+ Arabica::SAX2DOM::Parser<std::string> parser;
+ std::stringstream* ss = new std::stringstream();
+ (*ss) << srcContent.str();
+ std::auto_ptr<std::istream> ssPtr(ss);
+ Arabica::SAX::InputSource<std::string> inputSource;
+ inputSource.setByteStream(ssPtr);
+ if (parser.parse(inputSource) && parser.getDocument()) {
+ dom = parser.getDocument();
+ return;
+ } else {
+ text = srcContent.str();
+ return;
+ }
+ }
+ }
+
+ if (!node.hasChildNodes())
+ return;
+
+ Node<std::string> child = node.getFirstChild();
+ while(child) {
+ if (child.getNodeType() == Node_base::TEXT_NODE) {
+ std::string trimmed = child.getNodeValue();
+ boost::trim(trimmed);
+ if (trimmed.length() > 0)
+ break;
+ }
+ if (child.getNodeType() == Node_base::ELEMENT_NODE) {
+ break;
+ }
+ child = child.getNextSibling();
+ }
+ if (child && child.getNodeType() == Node_base::ELEMENT_NODE) {
+ DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
+ dom = domFactory.createDocument(child.getNamespaceURI(), "", 0);
+ Node<std::string> newNode = dom.importNode(child, true);
+ dom.appendChild(newNode);
+ } else if(child && child.getNodeType() == Node_base::TEXT_NODE) {
+ text = child.getNodeValue();
+ } else {
+ LOG(ERROR) << LOCALNAME(node) << " has neither text nor element children.";
+ }
}
void InterpreterImpl::processParamChilds(const Arabica::DOM::Node<std::string>& element, std::multimap<std::string, std::string>& params) {
@@ -726,7 +708,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) {
*/
sendReq.sendid = ATTR(getParentState(element), "id") + "." + getUUID();
if (HAS_ATTR(element, "idlocation") && _dataModel) {
- _dataModel.assign(ATTR(element, "idlocation"), "'" + sendReq.sendid + "'", Element<std::string>());
+ _dataModel.assign(ATTR(element, "idlocation"), "'" + sendReq.sendid + "'");
} else {
sendReq.hideSendId = true;
}
@@ -796,7 +778,16 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) {
if (contents.size() > 1)
LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
if (contents.size() > 0) {
- processContentElement(contents[0], sendReq.dom, sendReq.content, sendReq.data);
+ std::string expr;
+ processContentElement(contents[0], sendReq.dom, sendReq.content, expr);
+ if (expr.length() > 0 && _dataModel) {
+ try {
+ sendReq.content =_dataModel.evalAsString(expr);
+ } catch (Event e) {
+ e.name = "error.execution";
+ receiveInternal(e);
+ }
+ }
}
} catch (Event e) {
LOG(ERROR) << "Syntax error in send element content:" << std::endl << e << std::endl;
@@ -880,7 +871,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) {
} else {
invokeReq.invokeid = ATTR(getParentState(element), "id") + "." + getUUID();
if (HAS_ATTR(element, "idlocation") && _dataModel) {
- _dataModel.assign(ATTR(element, "idlocation"), "'" + invokeReq.invokeid + "'", Element<std::string>());
+ _dataModel.assign(ATTR(element, "idlocation"), "'" + invokeReq.invokeid + "'");
}
}
} catch (Event e) {
@@ -914,7 +905,16 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) {
if (contents.size() > 1)
LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
if (contents.size() > 0) {
- processContentElement(contents[0], invokeReq.dom, invokeReq.content, invokeReq.data);
+ std::string expr;
+ processContentElement(contents[0], invokeReq.dom, invokeReq.content, expr);
+ if (expr.length() > 0 && _dataModel) {
+ try {
+ invokeReq.content =_dataModel.evalAsString(expr);
+ } catch (Event e) {
+ e.name = "error.execution";
+ receiveInternal(e);
+ }
+ }
}
} catch (Event e) {
LOG(ERROR) << "Syntax error in send element content:" << std::endl << e << std::endl;
@@ -941,7 +941,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) {
}
if (_dataModel) {
try {
- _dataModel.assign("_invokers['" + invokeReq.invokeid + "']", invoker.getDataModelVariables(), Element<std::string>());
+ _dataModel.assign("_invokers['" + invokeReq.invokeid + "']", invoker.getDataModelVariables());
} catch(...) {
LOG(ERROR) << "Exception caught while assigning datamodel variables from invoker " << invokeReq.invokeid;
}
@@ -971,7 +971,7 @@ void InterpreterImpl::cancelInvoke(const Arabica::DOM::Node<std::string>& elemen
LOG(INFO) << "Removed invoker at " << invokeId;
if (_dataModel) {
try {
- _dataModel.assign("_invokers['" + invokeId + "']", "''", Element<std::string>());
+ _dataModel.assign("_invokers['" + invokeId + "']", std::string("''"));
} catch (Event e) {
LOG(ERROR) << "Syntax when removing invoker:" << std::endl << e << std::endl;
}
@@ -1139,13 +1139,13 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont
// assign array element to item
std::stringstream ss;
ss << array << "[" << iteration << "]";
- _dataModel.assign(item, ss.str(), Element<std::string>());
+ _dataModel.assign(item, ss.str());
}
if (index.length() > 0) {
// assign iteration element to index
std::stringstream ss;
ss << iteration;
- _dataModel.assign(index,ss.str(), Element<std::string>());
+ _dataModel.assign(index, ss.str());
}
if (content.hasChildNodes())
// execute content and have exception rethrown to break foreach
@@ -1183,21 +1183,10 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont
LOG(ERROR) << "Assigning to undeclared location '" << ATTR(content, "location") << "' not allowed." << std::endl;
throw Event("error.execution", Event::PLATFORM);
} else {
- Data data;
Document<std::string> dom;
std::string text;
- processContentElement(content, dom, text, data);
-
- if (dom) {
- _dataModel.assign(ATTR(content, "location"), dom, Element<std::string>(content));
- } else if(data && _dataModel.supportsJSON()) {
- _dataModel.assign(ATTR(content, "location"), data, Element<std::string>(content));
- } else if (text.length() > 0) {
- _dataModel.assign(ATTR(content, "location"), text, Element<std::string>(content));
- } else {
- LOG(ERROR) << "Assign element does not specify any content" << std::endl;
- throw Event("error.execution", Event::PLATFORM);
- }
+ processDOMorText(content, dom, text);
+ _dataModel.assign(Element<std::string>(content), dom, text);
}
}
CATCH_AND_DISTRIBUTE("Syntax error in attributes of assign element:")
@@ -1554,6 +1543,22 @@ std::vector<std::string> InterpreterImpl::tokenizeIdRefs(const std::string& idRe
return ids;
}
+std::string InterpreterImpl::spaceNormalize(const std::string& text) {
+ std::istringstream iss(text);
+ std::stringstream content;
+ std::string seperator;
+ do {
+ std::string token;
+ iss >> token;
+ if (token.length() > 0) {
+ content << seperator << token;
+ seperator = " ";
+ }
+ } while (iss);
+ return content.str();
+}
+
+
NodeSet<std::string> InterpreterImpl::filterChildElements(const std::string& tagName, const NodeSet<std::string>& nodeSet) {
NodeSet<std::string> filteredChildElems;
for (unsigned int i = 0; i < nodeSet.size(); i++) {
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index 673cba1..5207930 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -202,6 +202,7 @@ public:
static bool isDescendant(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2);
static std::vector<std::string> tokenizeIdRefs(const std::string& idRefs);
+ static std::string spaceNormalize(const std::string& text);
bool isInitial(const Arabica::DOM::Node<std::string>& state);
Arabica::XPath::NodeSet<std::string> getInitialStates(Arabica::DOM::Node<std::string> state = Arabica::DOM::Node<std::string>());
@@ -270,8 +271,12 @@ protected:
void processContentElement(const Arabica::DOM::Node<std::string>& element,
Arabica::DOM::Document<std::string>& dom,
std::string& text,
- Data& data);
- void processParamChilds(const Arabica::DOM::Node<std::string>& element, std::multimap<std::string, std::string>& params);
+ std::string& expr);
+ void processParamChilds(const Arabica::DOM::Node<std::string>& element,
+ std::multimap<std::string, std::string>& params);
+ void processDOMorText(const Arabica::DOM::Node<std::string>& node,
+ Arabica::DOM::Document<std::string>& dom,
+ std::string& text);
void send(const Arabica::DOM::Node<std::string>& element);
void invoke(const Arabica::DOM::Node<std::string>& element);
@@ -414,9 +419,22 @@ public:
return _impl->getCurrentEvent();
}
+#ifndef SWIG
Arabica::XPath::NodeSet<std::string> getConfiguration() {
return _impl->getConfiguration();
}
+#else
+ // simplified access to state names for language bindings
+ std::vector<std::string> getConfiguration() {
+ std::vector<std::string> stateNames;
+ Arabica::XPath::NodeSet<std::string> nodeSet = _impl->getConfiguration();
+ for (int i = 0; i < nodeSet.size(); i++) {
+ stateNames.push_back(ATTR(nodeSet[i], "id"));
+ }
+ return stateNames;
+ }
+#endif
+
void setConfiguration(const std::vector<std::string>& states) {
return _impl->setConfiguration(states);
}
@@ -507,6 +525,9 @@ public:
static std::vector<std::string> tokenizeIdRefs(const std::string& idRefs) {
return InterpreterImpl::tokenizeIdRefs(idRefs);
}
+ static std::string spaceNormalize(const std::string& text) {
+ return InterpreterImpl::spaceNormalize(text);
+ }
bool isInitial(const Arabica::DOM::Node<std::string>& state) {
return _impl->isInitial(state);
diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp
index 65a66ce..0898cc7 100644
--- a/src/uscxml/Message.cpp
+++ b/src/uscxml/Message.cpp
@@ -7,6 +7,8 @@
#include <SAX/helpers/CatchErrorHandler.hpp>
#include <glog/logging.h>
+#include <boost/algorithm/string.hpp>
+
#ifdef HAS_STRING_H
#include <string.h>
#endif
@@ -180,7 +182,10 @@ Data Data::fromXML(const std::string& xmlString) {
Data Data::fromJSON(const std::string& jsonString) {
Data data;
- if (jsonString.length() == 0)
+ std::string trimmed = jsonString;
+ boost::trim(trimmed);
+
+ if (trimmed.length() == 0)
return data;
jsmn_parser p;
@@ -194,7 +199,7 @@ Data Data::fromJSON(const std::string& jsonString) {
jsmn_init(&p);
frac /= 2;
- int nrTokens = jsonString.size() / frac;
+ int nrTokens = trimmed.size() / frac;
if (t != NULL) {
free(t);
// LOG(INFO) << "Increasing JSON length to token ratio to 1/" << frac;
@@ -206,7 +211,7 @@ Data Data::fromJSON(const std::string& jsonString) {
}
memset(t, 0, nrTokens * sizeof(jsmntok_t) + 1);
- rv = jsmn_parse(&p, jsonString.c_str(), t, nrTokens);
+ rv = jsmn_parse(&p, trimmed.c_str(), t, nrTokens);
} while (rv == JSMN_ERROR_NOMEM && frac > 1);
if (rv != 0) {
@@ -227,6 +232,9 @@ Data Data::fromJSON(const std::string& jsonString) {
return data;
}
+ if (t[0].end != trimmed.length())
+ return data;
+
std::list<Data*> dataStack;
std::list<jsmntok_t> tokenStack;
dataStack.push_back(&data);
@@ -237,7 +245,7 @@ Data Data::fromJSON(const std::string& jsonString) {
case JSMN_STRING:
dataStack.back()->type = Data::VERBATIM;
case JSMN_PRIMITIVE:
- dataStack.back()->atom = jsonString.substr(t[currTok].start, t[currTok].end - t[currTok].start);
+ dataStack.back()->atom = trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start);
dataStack.pop_back();
currTok++;
break;
@@ -258,7 +266,7 @@ Data Data::fromJSON(const std::string& jsonString) {
if (tokenStack.back().type == JSMN_OBJECT && (t[currTok].type == JSMN_PRIMITIVE || t[currTok].type == JSMN_STRING)) {
// grab key and push new data
- dataStack.push_back(&(dataStack.back()->compound[jsonString.substr(t[currTok].start, t[currTok].end - t[currTok].start)]));
+ dataStack.push_back(&(dataStack.back()->compound[trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start)]));
currTok++;
}
if (tokenStack.back().type == JSMN_ARRAY) {
diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp
index dfcc457..d3019d9 100644
--- a/src/uscxml/interpreter/InterpreterDraft6.cpp
+++ b/src/uscxml/interpreter/InterpreterDraft6.cpp
@@ -22,6 +22,8 @@ void InterpreterDraft6::interpret() {
// just make sure we have a session id
assert(_sessionId.length() > 0);
+ setupIOProcessors();
+
std::string datamodelName;
if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "datamodel"))
datamodelName = ATTR(_scxml, "datamodel");
@@ -34,11 +36,9 @@ void InterpreterDraft6::interpret() {
}
if (_dataModel) {
- _dataModel.assign("_x.args", _cmdLineOptions, Element<std::string>());
+ _dataModel.assign("_x.args", _cmdLineOptions);
}
- setupIOProcessors();
-
_running = true;
_binding = (HAS_ATTR(_scxml, "binding") && boost::iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY);
diff --git a/src/uscxml/interpreter/InterpreterDraft7.cpp b/src/uscxml/interpreter/InterpreterDraft7.cpp
index e02a343..2f8c7b2 100644
--- a/src/uscxml/interpreter/InterpreterDraft7.cpp
+++ b/src/uscxml/interpreter/InterpreterDraft7.cpp
@@ -45,12 +45,7 @@ void InterpreterDraft7::interpret() {
}
if (_dataModel) {
- _dataModel.assign("_x.args", _cmdLineOptions, Element<std::string>());
- if (_httpServlet) {
- Data data;
- data.compound["location"] = Data(_httpServlet->getURL(), Data::VERBATIM);
- _dataModel.assign("_ioprocessors['http']", data, Element<std::string>());
- }
+ _dataModel.assign("_x.args", _cmdLineOptions);
}
setupIOProcessors();
@@ -117,54 +112,6 @@ void InterpreterDraft7::interpret() {
}
/**
- * Called with a single data element from the topmost datamodel element.
- */
-void InterpreterDraft7::initializeData(const Arabica::DOM::Element<std::string>& data) {
- if (!_dataModel) {
- LOG(ERROR) << "Cannot initialize data when no datamodel is given!";
- return;
- }
- try {
- if (!HAS_ATTR(data, "id")) {
- LOG(ERROR) << "Data element has no id!";
- return;
- }
-
- if (HAS_ATTR(data, "expr")) {
- std::string value = ATTR(data, "expr");
- _dataModel.assign(ATTR(data, "id"), value, data);
- } else if (HAS_ATTR(data, "src")) {
- URL srcURL(ATTR(data, "src"));
- if (!srcURL.isAbsolute())
- toAbsoluteURI(srcURL);
-
- std::stringstream ss;
- if (_cachedURLs.find(srcURL.asString()) != _cachedURLs.end()) {
- ss << _cachedURLs[srcURL.asString()];
- } else {
- ss << srcURL;
- _cachedURLs[srcURL.asString()] = srcURL;
- }
- _dataModel.assign(ATTR(data, "id"), ss.str(), data);
-
- } else if (data.hasChildNodes()) {
- // search for the text node with the actual script
- NodeList<std::string> dataChilds = data.getChildNodes();
- for (int i = 0; i < dataChilds.getLength(); i++) {
- if (dataChilds.item(i).getNodeType() == Node_base::TEXT_NODE) {
- Data value = Data(dataChilds.item(i).getNodeValue());
- _dataModel.assign(ATTR(data, "id"), value, data);
- break;
- }
- }
- }
-
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in data element:" << std::endl << e << std::endl;
- }
-}
-
-/**
procedure mainEventLoop():
while running:
enabledTransitions = null
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
index 2491fc4..22777fa 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
@@ -147,9 +147,13 @@ void V8DataModel::setEvent(const Event& event) {
if (event.dom) {
eventObj->Set(v8::String::New("data"), getDocumentAsValue(event.dom));
} else if (event.content.length() > 0) {
- // _event.data is a string
- eventObj->Set(v8::String::New("data"), v8::String::New(event.content.c_str()));
-// eventObj->Set(v8::String::New("data"), v8::Undefined());
+ // _event.data is a string or JSON
+ Data json = Data::fromJSON(event.content);
+ if (json) {
+ eventObj->Set(v8::String::New("data"), getDataAsValue(json));
+ } else {
+ eventObj->Set(v8::String::New("data"), v8::String::New(Interpreter::spaceNormalize(event.content).c_str()));
+ }
} else {
// _event.data is KVP
Event eventCopy(event);
@@ -188,12 +192,23 @@ Data V8DataModel::getStringAsData(const std::string& content) {
}
Data V8DataModel::getValueAsData(const v8::Handle<v8::Value>& value) {
+ std::set<v8::Value*> foo = std::set<v8::Value*>();
+ return getValueAsData(value, foo);
+}
+
+Data V8DataModel::getValueAsData(const v8::Handle<v8::Value>& value, std::set<v8::Value*>& alreadySeen) {
Data data;
+
+ /// TODO: Breaking cycles does not work yet
+ if (alreadySeen.find(*value) != alreadySeen.end())
+ return data;
+ alreadySeen.insert(*value);
+
if (false) {
} else if (value->IsArray()) {
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
for (int i = 0; i < array->Length(); i++) {
- data.array.push_back(getValueAsData(array->Get(i)));
+ data.array.push_back(getValueAsData(array->Get(i), alreadySeen));
}
} else if (value->IsBoolean()) {
data.atom = (value->ToBoolean()->Value() ? "true" : "false");
@@ -226,7 +241,7 @@ Data V8DataModel::getValueAsData(const v8::Handle<v8::Value>& value) {
assert(properties->Get(i)->IsString());
v8::String::AsciiValue key(v8::Handle<v8::String>::Cast(properties->Get(i)));
v8::Local<v8::Value> property = object->Get(properties->Get(i));
- data.compound[*key] = getValueAsData(property);
+ data.compound[*key] = getValueAsData(property, alreadySeen);
}
} else if (value->IsRegExp()) {
LOG(ERROR) << "IsRegExp is unimplemented" << std::endl;
@@ -374,9 +389,33 @@ std::string V8DataModel::evalAsString(const std::string& expr) {
v8::Context::Scope contextScope(_contexts.back());
v8::Handle<v8::Value> result = evalAsValue(expr);
if (result->IsObject()) {
+ v8::Local<v8::Object> obj = result->ToObject();
+ v8::Local<v8::Object> proto;
+
+ proto = obj->FindInstanceInPrototypeChain(Arabica::DOM::V8Document::getTmpl());
+ if (!proto.IsEmpty()) {
+ struct Arabica::DOM::V8Document::V8DocumentPrivate* privData =
+ Arabica::DOM::V8DOM::toClassPtr<Arabica::DOM::V8Document::V8DocumentPrivate >(obj->GetInternalField(0));
+ std::stringstream ss;
+ ss << privData->nativeObj->getDocumentElement();
+ return ss.str();
+ }
+
+ proto = obj->FindInstanceInPrototypeChain(Arabica::DOM::V8Node::getTmpl());
+ if (!proto.IsEmpty()) {
+ struct Arabica::DOM::V8Node::V8NodePrivate* privData =
+ Arabica::DOM::V8DOM::toClassPtr<Arabica::DOM::V8Node::V8NodePrivate >(obj->GetInternalField(0));
+ std::stringstream ss;
+ ss << privData->nativeObj;
+ return ss.str();
+ }
+
Data data = getValueAsData(result);
return toStr(data);
}
+ if (result->IsNumber()) {
+ return toStr(result->ToNumber()->NumberValue());
+ }
v8::String::AsciiValue data(result->ToString());
return std::string(*data);
}
@@ -392,40 +431,89 @@ double V8DataModel::evalAsNumber(const std::string& expr) {
return 0;
}
-void V8DataModel::assign(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& dataElem) {
+void V8DataModel::assign(const Arabica::DOM::Element<std::string>& assignElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content) {
v8::Locker locker;
v8::HandleScope handleScope;
v8::Context::Scope contextScope(_contexts.front());
v8::Handle<v8::Object> global = _contexts.front()->Global();
- global->Set(v8::String::New(location.c_str()), getDocumentAsValue(doc));
-
+ std::string key;
+ if (HAS_ATTR(assignElem, "id")) {
+ key = ATTR(assignElem, "id");
+ } else if (HAS_ATTR(assignElem, "location")) {
+ key = ATTR(assignElem, "location");
+ }
+ if (key.length() == 0)
+ throw Event("error.execution", Event::PLATFORM);
+
+ if (HAS_ATTR(assignElem, "expr")) {
+ evalAsValue(key + " = " + ATTR(assignElem, "expr"));
+ } else if (doc) {
+ global->Set(v8::String::New(key.c_str()), getDocumentAsValue(doc));
+ } else if (content.size() > 0) {
+ try {
+ evalAsValue(key + " = " + content);
+ } catch (...) {
+ evalAsValue(key + " = " + "\"" + Interpreter::spaceNormalize(content) + "\"");
+ }
+ } else {
+ global->Set(v8::String::New(key.c_str()), v8::Undefined());
+ }
}
void V8DataModel::assign(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& dataElem) {
+ const Data& data) {
v8::Locker locker;
v8::HandleScope handleScope;
v8::Context::Scope contextScope(_contexts.front());
std::stringstream ssJSON;
ssJSON << data;
- assign(location, ssJSON.str(), dataElem);
+ evalAsValue(location + " = " + ssJSON.str());
}
-void V8DataModel::assign(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& dataElem) {
- v8::Locker locker;
- v8::HandleScope handleScope;
- v8::Context::Scope contextScope(_contexts.back());
- evalAsValue(location + " = " + expr);
+void V8DataModel::init(const Arabica::DOM::Element<std::string>& dataElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content) {
+ try {
+ assign(dataElem, doc, content);
+ } catch (Event e) {
+ // test 277
+ std::string key;
+ if (HAS_ATTR(dataElem, "id")) {
+ key = ATTR(dataElem, "id");
+ } else if (HAS_ATTR(dataElem, "location")) {
+ key = ATTR(dataElem, "location");
+ }
+ v8::Locker locker;
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(_contexts.front());
+
+ evalAsValue(key + " = undefined", true);
+ throw e;
+ }
+};
+
+void V8DataModel::init(const std::string& location,
+ const Data& data) {
+ try {
+ assign(location, data);
+ } catch (Event e) {
+ // test 277
+ v8::Locker locker;
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(_contexts.front());
+
+ evalAsValue(location + " = undefined", true);
+ throw e;
+ }
+
}
-v8::Handle<v8::Value> V8DataModel::evalAsValue(const std::string& expr) {
+
+v8::Handle<v8::Value> V8DataModel::evalAsValue(const std::string& expr, bool dontThrow) {
v8::TryCatch tryCatch;
v8::Handle<v8::String> source = v8::String::New(expr.c_str());
v8::Handle<v8::Script> script = v8::Script::Compile(source);
@@ -436,7 +524,7 @@ v8::Handle<v8::Value> V8DataModel::evalAsValue(const std::string& expr) {
if (script.IsEmpty() || result.IsEmpty()) {
// throw an exception
- if (tryCatch.HasCaught())
+ if (tryCatch.HasCaught() && !dontThrow)
throwExceptionEvent(tryCatch);
}
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
index 7bea50c..7c4f2b3 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
@@ -39,36 +39,26 @@ public:
virtual void pushContext();
virtual void popContext();
- virtual bool supportsJSON() { return true; }
+ virtual bool supportsJSON() {
+ return true;
+ }
virtual void eval(const std::string& expr);
+ virtual void assign(const Arabica::DOM::Element<std::string>& assignElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content);
virtual void assign(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& assignElem);
- virtual void assign(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& assignElem);
- virtual void assign(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& assignElem);
-
- virtual void init(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& dataElem) {
- assign(location, doc, dataElem);
- };
- virtual void init(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& dataElem) {
- assign(location, expr, dataElem);
- }
+ const Data& data);
+
+ virtual void init(const Arabica::DOM::Element<std::string>& dataElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content);
virtual void init(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& dataElem) {
- assign(location, data, dataElem);
- }
+ const Data& data);
virtual Data getStringAsData(const std::string& content);
+ virtual Data getValueAsData(const v8::Handle<v8::Value>& value,
+ std::set<v8::Value*>& alreadySeen);
virtual Data getValueAsData(const v8::Handle<v8::Value>& value);
virtual bool isDeclared(const std::string& expr);
@@ -90,7 +80,7 @@ protected:
static v8::Handle<v8::Value> getAttribute(v8::Local<v8::String> property, const v8::AccessorInfo& info);
static void setWithException(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
- v8::Handle<v8::Value> evalAsValue(const std::string& expr);
+ v8::Handle<v8::Value> evalAsValue(const std::string& expr, bool dontThrow = false);
v8::Handle<v8::Value> getDataAsValue(const Data& data);
v8::Handle<v8::Value> getDocumentAsValue(const Arabica::DOM::Document<std::string>& doc);
void throwExceptionEvent(const v8::TryCatch& tryCatch);
diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp
index 69970dd..6911480 100644
--- a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp
@@ -52,7 +52,7 @@ bool NULLDataModel::validate(const std::string& location, const std::string& sch
}
uint32_t NULLDataModel::getLength(const std::string& expr) {
- return 0;
+ return 0;
}
void NULLDataModel::eval(const std::string& expr) {
@@ -63,9 +63,9 @@ bool NULLDataModel::isDeclared(const std::string& expr) {
}
/**
- * The boolean expression language consists of the In predicate only. It has the
- * form 'In(id)', where id is the id of a state in the enclosing state machine.
- * The predicate must return 'true' if and only if that state is in the current
+ * The boolean expression language consists of the In predicate only. It has the
+ * form 'In(id)', where id is the id of a state in the enclosing state machine.
+ * The predicate must return 'true' if and only if that state is in the current
* state configuration.
*/
bool NULLDataModel::evalAsBool(const std::string& expr) {
@@ -73,14 +73,14 @@ bool NULLDataModel::evalAsBool(const std::string& expr) {
boost::trim(trimmedExpr);
if (!boost::istarts_with(trimmedExpr, "in"))
return false;
-
+
// find string in between brackets
size_t start = trimmedExpr.find_first_of("(");
size_t end = trimmedExpr.find_last_of(")");
if (start == std::string::npos || end == std::string::npos || start >= end)
return false;
start++;
-
+
// split at comma
std::stringstream ss(trimmedExpr.substr(start, end - start));
std::vector<std::string> stateExprs;
@@ -88,7 +88,7 @@ bool NULLDataModel::evalAsBool(const std::string& expr) {
while(std::getline(ss, item, ',')) {
stateExprs.push_back(item);
}
-
+
for (unsigned int i = 0; i < stateExprs.size(); i++) {
// remove ticks
size_t start = stateExprs[i].find_first_of("'");
@@ -101,7 +101,7 @@ bool NULLDataModel::evalAsBool(const std::string& expr) {
} else {
stateName = stateExprs[i];
}
-
+
if (Interpreter::isMember(_interpreter->getState(stateName), _interpreter->getConfiguration())) {
continue;
}
diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.h b/src/uscxml/plugins/datamodel/null/NULLDataModel.h
index eaa9dbd..423c5ff 100644
--- a/src/uscxml/plugins/datamodel/null/NULLDataModel.h
+++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.h
@@ -36,30 +36,20 @@ public:
virtual void pushContext();
virtual void popContext();
- virtual void eval(const std::string& expr);
- virtual void assign(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& assignElem) {}
- virtual void assign(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& assignElem) {}
- virtual void assign(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& assignElem) {}
-
- virtual void init(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& dataElem) {};
- virtual void init(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& dataElem) {};
- virtual void init(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& dataElem) {};
+ virtual void assign(const Arabica::DOM::Element<std::string>& assignElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content) {}
+ virtual void assign(const std::string& location, const Data& data) {}
+
+ virtual void init(const Arabica::DOM::Element<std::string>& dataElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content) {}
+ virtual void init(const std::string& location, const Data& data) {}
virtual Data getStringAsData(const std::string& content);
virtual bool isDeclared(const std::string& expr);
+ virtual void eval(const std::string& expr);
virtual std::string evalAsString(const std::string& expr);
virtual bool evalAsBool(const std::string& expr);
virtual double evalAsNumber(const std::string& expr);
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
index 75d6da9..f3af4b6 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
@@ -21,7 +21,7 @@ bool connect(pluma::Host& host) {
SWIDataModel::SWIDataModel() {
}
-boost::shared_ptr<DataModelImpl> SWIDataModel::create(Interpreter* interpreter) {
+boost::shared_ptr<DataModelImpl> SWIDataModel::create(InterpreterImpl* interpreter) {
boost::shared_ptr<SWIDataModel> dm = boost::shared_ptr<SWIDataModel>(new SWIDataModel());
dm->_interpreter = interpreter;
@@ -134,16 +134,41 @@ std::string SWIDataModel::evalAsString(const std::string& expr) {
return std::string(compound);
}
-void SWIDataModel::assign(const std::string& location, const Data& data) {
- eval(data.atom);
+void SWIDataModel::assign(const std::string& location,
+ const Arabica::DOM::Document<std::string>& doc,
+ const Arabica::DOM::Element<std::string>& assignElem) {
+
}
+void SWIDataModel::assign(const std::string& location,
+ const std::string& expr,
+ const Arabica::DOM::Element<std::string>& assignElem) {
-void SWIDataModel::assign(const std::string& location, const std::string& expr) {
eval(expr);
}
+void SWIDataModel::assign(const std::string& location,
+ const Data& data,
+ const Arabica::DOM::Element<std::string>& assignElem) {
+ eval(data.atom);
+}
+
+void SWIDataModel::init(const std::string& location,
+ const Arabica::DOM::Document<std::string>& doc,
+ const Arabica::DOM::Element<std::string>& dataElem) {
+
+}
+void SWIDataModel::init(const std::string& location,
+ const std::string& expr,
+ const Arabica::DOM::Element<std::string>& dataElem) {
+
+}
+void SWIDataModel::init(const std::string& location,
+ const Data& data,
+ const Arabica::DOM::Element<std::string>& dataElem) {
-bool SWIDataModel::isDefined(const std::string& expr) {
+}
+
+bool SWIDataModel::isDeclared(const std::string& expr) {
return true;
}
-} \ No newline at end of file
+}
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
index 52d1e34..5d95476 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
@@ -15,7 +15,7 @@ class SWIDataModel : public DataModelImpl {
public:
SWIDataModel();
virtual ~SWIDataModel();
- virtual boost::shared_ptr<DataModelImpl> create(Interpreter* interpreter);
+ virtual boost::shared_ptr<DataModelImpl> create(InterpreterImpl* interpreter);
virtual std::set<std::string> getNames() {
std::set<std::string> names;
@@ -37,20 +37,39 @@ public:
virtual void popContext();
virtual void eval(const std::string& expr);
- virtual void assign(const std::string& location, const std::string& expr);
- virtual void assign(const std::string& location, const Data& data);
- virtual bool isDefined(const std::string& expr);
+ virtual bool isDeclared(const std::string& expr);
virtual Data getStringAsData(const std::string& content);
virtual std::string evalAsString(const std::string& expr);
virtual bool evalAsBool(const std::string& expr);
+ virtual void assign(const std::string& location,
+ const Arabica::DOM::Document<std::string>& doc,
+ const Arabica::DOM::Element<std::string>& assignElem);
+ virtual void assign(const std::string& location,
+ const std::string& expr,
+ const Arabica::DOM::Element<std::string>& assignElem);
+ virtual void assign(const std::string& location,
+ const Data& data,
+ const Arabica::DOM::Element<std::string>& assignElem);
+
+ virtual void init(const std::string& location,
+ const Arabica::DOM::Document<std::string>& doc,
+ const Arabica::DOM::Element<std::string>& dataElem);
+ virtual void init(const std::string& location,
+ const std::string& expr,
+ const Arabica::DOM::Element<std::string>& dataElem);
+ virtual void init(const std::string& location,
+ const Data& data,
+ const Arabica::DOM::Element<std::string>& dataElem);
protected:
Event _event;
PlEngine* _plEngine;
+ std::string _name;
+ std::string _sessionId;
};
#ifdef BUILD_AS_PLUGINS
diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
index f874c86..eef8e51 100644
--- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
@@ -27,7 +27,7 @@ XPathDataModel::XPathDataModel() {
boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterImpl* interpreter) {
boost::shared_ptr<XPathDataModel> dm = boost::shared_ptr<XPathDataModel>(new XPathDataModel());
dm->_interpreter = interpreter;
-// dm->_xpath.setVariableResolver(_varResolver);
+
// dm->_xpath->setVariableCompileTimeResolver(_varCTResolver);
// dm->_xpath->setNamespaceContext(interpreter->getNSContext());
@@ -39,21 +39,21 @@ boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterImpl* interpr
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);
@@ -61,8 +61,7 @@ boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterImpl* interpr
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());
@@ -73,13 +72,13 @@ boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterImpl* interpr
sessIdNodeSet.push_back(sessIdElem);
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(nameElem);
dm->_varResolver.setVariable("_name", nameNodeSet);
@@ -104,7 +103,7 @@ void XPathDataModel::setEvent(const Event& event) {
eventElem.setAttribute("id", "_event");
Element<std::string> eventDataElem = _doc.createElement("data");
-
+
NodeSet<std::string> eventNodeSet;
if (event.params.size() > 0) {
std::multimap<std::string, std::string>::const_iterator paramIter = event.params.begin();
@@ -131,14 +130,17 @@ void XPathDataModel::setEvent(const Event& event) {
}
}
if (event.content.size() > 0) {
- eventDataElem.setNodeValue(event.content);
+ Text<std::string> textNode = _doc.createTextNode(Interpreter::spaceNormalize(event.content).c_str());
+ eventDataElem.appendChild(textNode);
+ }
+ if (event.dom) {
+ Node<std::string> importedNode = _doc.importNode(event.dom.getFirstChild(), true);
+ eventDataElem.appendChild(importedNode);
}
-
+
eventElem.appendChild(eventDataElem);
eventNodeSet.push_back(eventElem);
-
-// std::cout << eventElem << std::endl;
-
+
// do we need to replace an existing event?
Node<std::string> oldEventElem = _datamodel.getFirstChild();
while(oldEventElem) {
@@ -148,7 +150,7 @@ void XPathDataModel::setEvent(const Event& event) {
}
oldEventElem = oldEventElem.getNextSibling();
}
-
+
if (oldEventElem) {
_datamodel.replaceChild(eventElem, oldEventElem);
} else {
@@ -167,7 +169,7 @@ bool XPathDataModel::validate(const std::string& location, const std::string& sc
}
uint32_t XPathDataModel::getLength(const std::string& expr) {
- return 0;
+ return 0;
}
void XPathDataModel::eval(const std::string& expr) {
@@ -193,9 +195,87 @@ double XPathDataModel::evalAsNumber(const std::string& expr) {
return result.asNumber();
}
+void XPathDataModel::assign(const Arabica::DOM::Element<std::string>& assignElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ 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");
+ }
+
+ XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc);
+ NodeSet<std::string> nodeSet;
+ if (doc) {
+ nodeSet.push_back(doc.getDocumentElement());
+ assign(key, nodeSet, assignElem);
+ } else if (content.length() > 0) {
+ Text<std::string> textNode = _doc.createTextNode(Interpreter::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);
+ 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) {
+
+}
+
+void XPathDataModel::init(const Arabica::DOM::Element<std::string>& dataElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ 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");
+ }
+
+ Element<std::string> container = _doc.createElement("data");
+ container.setAttribute("id", location);
+ if (doc) {
+ Element<std::string> data = doc.getDocumentElement();
+ if (data.hasChildNodes()) {
+ Node<std::string> dataClone = _doc.importNode(data, true);
+ container.appendChild(dataClone);
+ }
+ } else if (content.length() > 0) {
+ Text<std::string> textNode = _doc.createTextNode(Interpreter::spaceNormalize(content));
+ container.appendChild(textNode);
+ } else if (HAS_ATTR(dataElem, "expr")) {
+ XPathValue<std::string> expr = _xpath.evaluate_expr(ATTR(dataElem, "expr"), _doc);
+ XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc);
+ assign(key, expr, dataElem);
+ for (int i = 0; expr.asNodeSet().size(); i++)
+ container.appendChild(expr.asNodeSet()[i]);
+ } else {
+ LOG(ERROR) << "data element has no content";
+ }
+ _datamodel.appendChild(container);
+
+ // put data element into nodeset and bind to xpath variable
+ NodeSet<std::string> nodeSet;
+ nodeSet.push_back(container);
+ _varResolver.setVariable(location, nodeSet);
+
+ std::cout << _datamodel << std::endl;
+}
+
+void XPathDataModel::init(const std::string& location, const Data& data) {
+
+}
+
+#if 0
void XPathDataModel::assign(const std::string& location,
- const Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& dataElem) {
+ const Document<std::string>& doc,
+ const Arabica::DOM::Element<std::string>& dataElem) {
XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc);
NodeSet<std::string> nodeSet;
nodeSet.push_back(doc.getDocumentElement());
@@ -203,15 +283,15 @@ void XPathDataModel::assign(const std::string& location,
}
void XPathDataModel::assign(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& dataElem) {
+ const Data& data,
+ const Arabica::DOM::Element<std::string>& dataElem) {
// assert(false);
// std::cout << location << " = " << data << std::endl;
}
void XPathDataModel::assign(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& dataElem) {
+ const std::string& expr,
+ const Arabica::DOM::Element<std::string>& dataElem) {
std::string realExpr = (HAS_ATTR(dataElem, "expr") ? ATTR(dataElem, "expr") : expr);
XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc);
XPathValue<std::string> value = _xpath.evaluate_expr(realExpr, _doc);
@@ -219,8 +299,8 @@ void XPathDataModel::assign(const std::string& location,
}
void XPathDataModel::init(const std::string& location,
- const Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& dataElem) {
+ const Document<std::string>& doc,
+ const Arabica::DOM::Element<std::string>& dataElem) {
Element<std::string> container = _doc.createElement("data");
container.setAttribute("id", location);
Element<std::string> data = doc.getDocumentElement();
@@ -229,7 +309,7 @@ void XPathDataModel::init(const std::string& location,
container.appendChild(dataClone);
}
_datamodel.appendChild(container);
-
+
// put data element into nodeset and bind to xpath variable
NodeSet<std::string> nodeSet;
nodeSet.push_back(container);
@@ -237,11 +317,11 @@ void XPathDataModel::init(const std::string& location,
}
void XPathDataModel::init(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& dataElem) {
+ const std::string& expr,
+ const Arabica::DOM::Element<std::string>& dataElem) {
Element<std::string> data = _doc.createElement("data");
data.setAttribute("id", location);
-
+
if (expr.length() > 0) {
Text<std::string> textNode = _doc.createTextNode(expr.c_str());
data.appendChild(textNode);
@@ -255,182 +335,195 @@ void XPathDataModel::init(const std::string& location,
}
void XPathDataModel::init(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& dataElem) {
- assert(false);
+ const Data& data,
+ const Arabica::DOM::Element<std::string>& dataElem) {
+// XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc);
+ init(location, data.atom, dataElem);
}
+#endif
void XPathDataModel::assign(XPathValue<std::string>& key,
- const XPathValue<std::string>& value,
- const Arabica::DOM::Element<std::string>& assignElem) {
+ const XPathValue<std::string>& value,
+ const Arabica::DOM::Element<std::string>& assignElem) {
switch (value.type()) {
- case STRING:
- assign(key, value.asString(), assignElem);
- break;
- case BOOL:
- assign(key, value.asBool(), assignElem);
- break;
- case NUMBER:
- assign(key, value.asNumber(), assignElem);
- break;
- case NODE_SET:
- assign(key, value.asNodeSet(), assignElem);
- break;
- case ANY:
- throw Event("error.execution", Event::PLATFORM);
+ case STRING:
+ assign(key, value.asString(), assignElem);
+ break;
+ case BOOL:
+ assign(key, value.asBool(), assignElem);
+ break;
+ case NUMBER:
+ assign(key, value.asNumber(), assignElem);
+ break;
+ case NODE_SET:
+ assign(key, value.asNodeSet(), assignElem);
+ break;
+ case ANY:
+ throw Event("error.execution", Event::PLATFORM);
}
}
void XPathDataModel::assign(XPathValue<std::string>& key,
- const std::string& value,
- const Arabica::DOM::Element<std::string>& assignElem) {
+ const std::string& value,
+ const Arabica::DOM::Element<std::string>& assignElem) {
switch (key.type()) {
- case NODE_SET: {
- if (key.asNodeSet().size() == 0)
- return;
- Node<std::string> node = key.asNodeSet()[0];
+ case NODE_SET: {
+ if (key.asNodeSet().size() == 0)
+ return;
+ for (int i = 0; i < key.asNodeSet().size(); i++) {
+ Node<std::string> node = key.asNodeSet()[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") && boost::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"))
- throw Event("error.execution", Event::PLATFORM);
- element.setAttribute(ATTR(assignElem, "attr"), value);
- }
- break;
+ 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") && boost::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"))
+ throw Event("error.execution", Event::PLATFORM);
+ 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);
}
- default:
- throw Event("error.execution", Event::PLATFORM);
- break;
+ break;
+ }
+ default:
+ throw Event("error.execution", Event::PLATFORM);
+ break;
}
- break;
}
- case STRING:
- case BOOL:
- case NUMBER:
- case ANY:
- throw Event("error.execution", Event::PLATFORM);
- break;
- default:
- break;
+ break;
+ }
+ case STRING:
+ case BOOL:
+ case NUMBER:
+ case ANY:
+ throw Event("error.execution", Event::PLATFORM);
+ break;
+ default:
+ break;
}
}
void XPathDataModel::assign(XPathValue<std::string>& key,
- const double value,
- const Arabica::DOM::Element<std::string>& assignElem) {
+ const double value,
+ const Arabica::DOM::Element<std::string>& assignElem) {
+ assign(key, toStr(value), assignElem);
}
void XPathDataModel::assign(XPathValue<std::string>& key,
- const bool value,
- const Arabica::DOM::Element<std::string>& assignElem) {
+ const bool value,
+ const Arabica::DOM::Element<std::string>& assignElem) {
}
void XPathDataModel::assign(XPathValue<std::string>& key,
- const NodeSet<std::string>& value,
- const Arabica::DOM::Element<std::string>& assignElem) {
+ const NodeSet<std::string>& value,
+ const Arabica::DOM::Element<std::string>& assignElem) {
switch (key.type()) {
- case NODE_SET: {
- if (key.asNodeSet().size() == 0)
- return;
- Node<std::string> node = key.asNodeSet()[0];
+ case NODE_SET: {
+ if (key.asNodeSet().size() == 0)
+ return;
+ for (int i = 0; i < key.asNodeSet().size(); i++) {
+ Node<std::string> node = key.asNodeSet()[i];
switch (node.getNodeType()) {
- case Node_base::ELEMENT_NODE: {
- Element<std::string> element(node);
- if (false) {
- } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "firstchild")) {
- // firstchild: Insert the value specified by 'expr' before all of the children at 'location'.
- for (int i = value.size(); i; i--) {
- Node<std::string> importedNode = _doc.importNode(value[i-1], true);
- element.insertBefore(importedNode, element.getFirstChild());
- }
- } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "lastchild")) {
- // lastchild: Insert the value specified by 'expr' after all of the children at 'location'.
- for (int i = 0; i < value.size(); i++) {
- Node<std::string> importedNode = _doc.importNode(value[i], true);
- element.appendChild(importedNode);
- }
- } else if (HAS_ATTR(assignElem, "type") && boost::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)
- throw Event("error.execution", Event::PLATFORM);
- for (int i = 0; i < value.size(); i++) {
- Node<std::string> importedNode = _doc.importNode(value[i], true);
- parent.insertBefore(importedNode, element);
- }
- } else if (HAS_ATTR(assignElem, "type") && boost::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)
- throw Event("error.execution", Event::PLATFORM);
- for (int i = value.size(); i; i--) {
- Node<std::string> importedNode = _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 (HAS_ATTR(assignElem, "type") && boost::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)
- throw Event("error.execution", Event::PLATFORM);
- if (value.size() != 1)
- throw Event("error.execution", Event::PLATFORM);
- Node<std::string> importedNode = _doc.importNode(value[0], true);
- parent.replaceChild(importedNode, element);
- } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "delete")) {
- // delete: Delete the node specified by 'location'. ('expr' is ignored.).
- Node<std::string> parent = element.getParentNode();
- if (!parent)
- throw Event("error.execution", Event::PLATFORM);
- 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 (int i = 0; i < value.size(); i++) {
- Node<std::string> importedNode = _doc.importNode(value[i], true);
- element.appendChild(importedNode);
+ case Node_base::ELEMENT_NODE: {
+ Element<std::string> element(node);
+ if (false) {
+ } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "firstchild")) {
+ // firstchild: Insert the value specified by 'expr' before all of the children at 'location'.
+ for (int i = value.size(); i; i--) {
+ Node<std::string> importedNode = _doc.importNode(value[i-1], true);
+ element.insertBefore(importedNode, element.getFirstChild());
+ }
+ } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "lastchild")) {
+ // lastchild: Insert the value specified by 'expr' after all of the children at 'location'.
+ for (int i = 0; i < value.size(); i++) {
+ Node<std::string> importedNode = _doc.importNode(value[i], true);
+ element.appendChild(importedNode);
+ }
+ } else if (HAS_ATTR(assignElem, "type") && boost::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)
+ throw Event("error.execution", Event::PLATFORM);
+ for (int i = 0; i < value.size(); i++) {
+ Node<std::string> importedNode = _doc.importNode(value[i], true);
+ parent.insertBefore(importedNode, element);
+ }
+ } else if (HAS_ATTR(assignElem, "type") && boost::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)
+ throw Event("error.execution", Event::PLATFORM);
+ for (int i = value.size(); i; i--) {
+ Node<std::string> importedNode = _doc.importNode(value[i-1], true);
+ Node<std::string> nextSibling = element.getNextSibling();
+ if (nextSibling) {
+ parent.insertBefore(importedNode, element.getNextSibling());
+ } else {
+ parent.appendChild(importedNode);
}
}
- break;
+ } else if (HAS_ATTR(assignElem, "type") && boost::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)
+ throw Event("error.execution", Event::PLATFORM);
+ if (value.size() != 1)
+ throw Event("error.execution", Event::PLATFORM);
+ Node<std::string> importedNode = _doc.importNode(value[0], true);
+ parent.replaceChild(importedNode, element);
+ } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "delete")) {
+ // delete: Delete the node specified by 'location'. ('expr' is ignored.).
+ Node<std::string> parent = element.getParentNode();
+ if (!parent)
+ throw Event("error.execution", Event::PLATFORM);
+ 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 (int i = 0; i < value.size(); i++) {
+ Node<std::string> importedNode = _doc.importNode(value[i], true);
+ element.appendChild(importedNode);
+ }
}
- default:
- throw Event("error.execution", Event::PLATFORM);
- break;
+ break;
+ }
+ default:
+ throw Event("error.execution", Event::PLATFORM);
+ break;
}
- break;
}
- case STRING:
- case BOOL:
- case NUMBER:
- case ANY:
- throw Event("error.execution", Event::PLATFORM);
- break;
+ break;
+ }
+ case STRING:
+ case BOOL:
+ case NUMBER:
+ case ANY:
+ throw Event("error.execution", Event::PLATFORM);
+ break;
}
}
XPathValue<std::string>
- NodeSetVariableResolver::resolveVariable(const std::string& namepaceUri,
- const std::string& name) const {
+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()) {
throw Event("error.execution");
@@ -439,15 +532,15 @@ XPathValue<std::string>
}
XPathFunction<std::string>*
- XPathFunctionResolver::resolveFunction(const std::string& namespace_uri,
- const std::string& name,
- const std::vector<XPathExpression<std::string> >& argExprs) const {
+XPathFunctionResolver::resolveFunction(const std::string& namespace_uri,
+ const std::string& name,
+ const std::vector<XPathExpression<std::string> >& argExprs) const {
if (boost::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"));
@@ -455,7 +548,7 @@ std::vector<std::pair<std::string, std::string> > XPathFunctionResolver::validNa
}
bool XPathFunctionIn::doEvaluate(const Node<std::string>& context,
- const ExecutionContext<std::string>& executionContext) const {
+ const ExecutionContext<std::string>& executionContext) const {
for (int i = 0; i < argCount(); i++) {
XPathValue<std::string> stateName = arg(i, context, executionContext);
if (stateName.type() == STRING) {
diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h
index d028129..5f5952c 100644
--- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h
+++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h
@@ -18,42 +18,44 @@ namespace uscxml {
class XPathFunctionIn : public Arabica::XPath::BooleanXPathFunction<std::string> {
public:
XPathFunctionIn(int minArgs,
- int maxArgs,
- const std::vector<Arabica::XPath::XPathExpression<std::string> >& args,
- InterpreterImpl* interpreter) :
+ int maxArgs,
+ const std::vector<Arabica::XPath::XPathExpression<std::string> >& args,
+ InterpreterImpl* interpreter) :
BooleanXPathFunction(minArgs, maxArgs, args),
_interpreter(interpreter) {}
protected:
bool doEvaluate(const Arabica::DOM::Node<std::string>& context,
- const Arabica::XPath::ExecutionContext<std::string>& executionContext) const;
+ const Arabica::XPath::ExecutionContext<std::string>& executionContext) const;
InterpreterImpl* _interpreter;
};
class XPathFunctionResolver : public Arabica::XPath::FunctionResolver<std::string> {
public:
virtual ~XPathFunctionResolver() { }
-
- virtual Arabica::XPath::XPathFunction<std::string>*
- resolveFunction(const std::string& namespace_uri,
- const std::string& name,
- const std::vector<Arabica::XPath::XPathExpression<std::string> >& argExprs) const;
-
- virtual std::vector<std::pair<std::string, std::string> > validNames() const;
- void setInterpreter(InterpreterImpl* interpreter) { _interpreter = interpreter; }
+
+ virtual Arabica::XPath::XPathFunction<std::string>*
+ resolveFunction(const std::string& namespace_uri,
+ const std::string& name,
+ const std::vector<Arabica::XPath::XPathExpression<std::string> >& argExprs) const;
+
+ virtual std::vector<std::pair<std::string, std::string> > validNames() const;
+ void setInterpreter(InterpreterImpl* interpreter) {
+ _interpreter = interpreter;
+ }
protected:
Arabica::XPath::StandardXPathFunctionResolver<std::string> _xpathFuncRes;
InterpreterImpl* _interpreter;
};
-
+
class NodeSetVariableResolver : public Arabica::XPath::VariableResolver<std::string> {
public:
Arabica::XPath::XPathValue<std::string> resolveVariable(const std::string& namepaceUri,
- const std::string& name) const;
+ const std::string& name) const;
void setVariable(const std::string& name, const Arabica::XPath::NodeSet<std::string>& value) {
_variables[name] = value;
}
-
+
private:
std::map<std::string, Arabica::XPath::NodeSet<std::string> > _variables;
};
@@ -80,25 +82,15 @@ public:
virtual void popContext();
virtual void eval(const std::string& expr);
- virtual void assign(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& assignElem);
- virtual void assign(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& assignElem);
- virtual void assign(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& assignElem);
-
- virtual void init(const std::string& location,
- const Arabica::DOM::Document<std::string>& doc,
- const Arabica::DOM::Element<std::string>& dataElem);
- virtual void init(const std::string& location,
- const std::string& expr,
- const Arabica::DOM::Element<std::string>& dataElem);
- virtual void init(const std::string& location,
- const Data& data,
- const Arabica::DOM::Element<std::string>& dataElem);
+ virtual void assign(const Arabica::DOM::Element<std::string>& assignElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content);
+ virtual void assign(const std::string& location, const Data& data);
+
+ virtual void init(const Arabica::DOM::Element<std::string>& dataElem,
+ const Arabica::DOM::Document<std::string>& doc,
+ const std::string& content);
+ virtual void init(const std::string& location, const Data& data);
virtual Data getStringAsData(const std::string& content);
virtual bool isDeclared(const std::string& expr);
@@ -114,21 +106,21 @@ protected:
Arabica::DOM::Document<std::string> _doc;
void assign(Arabica::XPath::XPathValue<std::string>& key,
- const Arabica::XPath::XPathValue<std::string>& value,
- const Arabica::DOM::Element<std::string>& assignElem);
+ const Arabica::XPath::XPathValue<std::string>& value,
+ const Arabica::DOM::Element<std::string>& assignElem);
void assign(Arabica::XPath::XPathValue<std::string>& key,
- const std::string& value,
- const Arabica::DOM::Element<std::string>& assignElem);
+ const std::string& value,
+ const Arabica::DOM::Element<std::string>& assignElem);
void assign(Arabica::XPath::XPathValue<std::string>& key,
- const double value,
- const Arabica::DOM::Element<std::string>& assignElem);
+ const double value,
+ const Arabica::DOM::Element<std::string>& assignElem);
void assign(Arabica::XPath::XPathValue<std::string>& key,
- const bool value,
- const Arabica::DOM::Element<std::string>& assignElem);
+ const bool value,
+ const Arabica::DOM::Element<std::string>& assignElem);
void assign(Arabica::XPath::XPathValue<std::string>& key,
- const Arabica::XPath::NodeSet<std::string>& value,
- const Arabica::DOM::Element<std::string>& assignElem);
-
+ const Arabica::XPath::NodeSet<std::string>& value,
+ const Arabica::DOM::Element<std::string>& assignElem);
+
NodeSetVariableResolver _varResolver;
XPathFunctionResolver _funcResolver;
diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
index fc2ac2b..9eafbcf 100644
--- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
+++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
@@ -48,9 +48,9 @@ void USCXMLInvoker::invoke(const InvokeRequest& req) {
} else if (req.dom) {
_invokedInterpreter = Interpreter::fromDOM(req.dom);
} else if (req.content.size() > 0) {
- LOG(ERROR) << "Instantiating nested SCXML interpreter by content or expr not supported yet";
+ _invokedInterpreter = Interpreter::fromXML(req.content);
} else {
- LOG(ERROR) << "Cannot invoke nested SCXML interpreter, neither src attribute nor DOM is given";
+ LOG(ERROR) << "Cannot invoke nested SCXML interpreter, neither src attribute nor content nor DOM is given";
}
if (_invokedInterpreter) {
DataModel dataModel(_invokedInterpreter.getImpl()->getDataModel());
diff --git a/test/samples/w3c/ecma/test530.scxml b/test/samples/w3c/ecma/test530.scxml
index 9361181..0090907 100644
--- a/test/samples/w3c/ecma/test530.scxml
+++ b/test/samples/w3c/ecma/test530.scxml
@@ -18,7 +18,9 @@ is evaluated at the right time, we should get invoke.done, otherwise an error -
</invoke>
<transition event="done.invoke" target="pass"/>
- <transition event="*" target="fail"/>
+ <transition event="*" target="fail">
+ <log expr="_event.name" />
+ </transition>
</state>
<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final>
diff --git a/test/src/test-arabica-xpath.cpp b/test/src/test-arabica-xpath.cpp
index 2bcf605..2991dc0 100644
--- a/test/src/test-arabica-xpath.cpp
+++ b/test/src/test-arabica-xpath.cpp
@@ -9,28 +9,25 @@
typedef string_adaptor SA;
-class NodeSetVariableResolver : public Arabica::XPath::VariableResolver<string_type, string_adaptor>
-{
- //typedef string_adaptorstring_adaptor;
+class NodeSetVariableResolver : public Arabica::XPath::VariableResolver<string_type, string_adaptor> {
+ //typedef string_adaptorstring_adaptor;
public:
- virtual Arabica::XPath::XPathValue<string_type, string_adaptor> resolveVariable(const string_type& /* namepace_uri */,
- const string_type& name) const
- {
- using namespace Arabica::XPath;
- typename VarMap::const_iterator n = map_.find(name);
- if(n == map_.end())
- throw UnboundVariableException(string_adaptor::asStdString(name));
- return XPathValue<string_type, string_adaptor>(new NodeSetValue<string_type, string_adaptor>((*n).second));
- } // resolveVariable
-
- void setVariable(const string_type& name, const Arabica::XPath::NodeSet<string_type, string_adaptor>& value)
- {
- map_[name] = value;
- } // setVariable
-
+ virtual Arabica::XPath::XPathValue<string_type, string_adaptor> resolveVariable(const string_type& /* namepace_uri */,
+ const string_type& name) const {
+ using namespace Arabica::XPath;
+ typename VarMap::const_iterator n = map_.find(name);
+ if(n == map_.end())
+ throw UnboundVariableException(string_adaptor::asStdString(name));
+ return XPathValue<string_type, string_adaptor>(new NodeSetValue<string_type, string_adaptor>((*n).second));
+ } // resolveVariable
+
+ void setVariable(const string_type& name, const Arabica::XPath::NodeSet<string_type, string_adaptor>& value) {
+ map_[name] = value;
+ } // setVariable
+
private:
- typedef std::map<string_type, Arabica::XPath::NodeSet<string_type, string_adaptor> > VarMap;
- VarMap map_;
+ typedef std::map<string_type, Arabica::XPath::NodeSet<string_type, string_adaptor> > VarMap;
+ VarMap map_;
}; // class NodeSetVariableResolver
Arabica::XPath::XPath<string_type, string_adaptor> parser;
@@ -50,49 +47,46 @@ Arabica::DOM::ProcessingInstruction<string_type, string_adaptor> processingInstr
Arabica::DOM::Document<string_type, string_adaptor> chapters_;
Arabica::DOM::Document<string_type, string_adaptor> numbers_;
-class StringVariableResolver : public Arabica::XPath::VariableResolver<string_type, string_adaptor>
-{
+class StringVariableResolver : public Arabica::XPath::VariableResolver<string_type, string_adaptor> {
public:
- virtual Arabica::XPath::XPathValue<string_type, string_adaptor> resolveVariable(const string_type& /* namespace_uri */,
- const string_type& name) const
- {
- using namespace Arabica::XPath;
- typename VarMap::const_iterator n = map_.find(name);
- if(n == map_.end())
- throw UnboundVariableException(string_adaptor::asStdString(name));
- return XPathValue<string_type, string_adaptor>(new StringValue<string_type, string_adaptor>((*n).second));
- } // resolveVariable
-
- void setVariable(const string_type& name, const string_type& value)
- {
- map_[name] = value;
- } // setVariable
-
+ virtual Arabica::XPath::XPathValue<string_type, string_adaptor> resolveVariable(const string_type& /* namespace_uri */,
+ const string_type& name) const {
+ using namespace Arabica::XPath;
+ typename VarMap::const_iterator n = map_.find(name);
+ if(n == map_.end())
+ throw UnboundVariableException(string_adaptor::asStdString(name));
+ return XPathValue<string_type, string_adaptor>(new StringValue<string_type, string_adaptor>((*n).second));
+ } // resolveVariable
+
+ void setVariable(const string_type& name, const string_type& value) {
+ map_[name] = value;
+ } // setVariable
+
private:
- typedef std::map<string_type, string_type> VarMap;
- VarMap map_;
+ typedef std::map<string_type, string_type> VarMap;
+ VarMap map_;
}; // StringVariableResolver
int main(int argc, char** argv) {
-
+
factory_ = Arabica::SimpleDOM::DOMImplementation<string_type, string_adaptor>::getDOMImplementation();
document_ = factory_.createDocument(SA::construct_from_utf8(""), SA::construct_from_utf8(""), 0);
root_ = document_.createElement("root");
document_.appendChild(root_);
assert(root_);
-
+
element1_ = document_.createElement(SA::construct_from_utf8("child1"));
element2_ = document_.createElement(SA::construct_from_utf8("child2"));
element3_ = document_.createElement(SA::construct_from_utf8("child3"));
-
+
element1_.setAttribute(SA::construct_from_utf8("one"), SA::construct_from_utf8("1"));
-
+
element2_.setAttribute(SA::construct_from_utf8("one"), SA::construct_from_utf8("1"));
element2_.setAttribute(SA::construct_from_utf8("two"), SA::construct_from_utf8("1"));
element2_.setAttribute(SA::construct_from_utf8("three"), SA::construct_from_utf8("1"));
element2_.setAttribute(SA::construct_from_utf8("four"), SA::construct_from_utf8("1"));
-
+
text_ = document_.createTextNode(SA::construct_from_utf8("data"));
comment_ = document_.createComment(SA::construct_from_utf8("comment"));
processingInstruction_ = document_.createProcessingInstruction(SA::construct_from_utf8("target"), SA::construct_from_utf8("data"));
@@ -101,13 +95,13 @@ int main(int argc, char** argv) {
element2_.appendChild(spinkle_);
element2_.appendChild(comment_);
element2_.appendChild(processingInstruction_);
-
+
attr_ = element1_.getAttributeNode(SA::construct_from_utf8("one"));
-
+
root_.appendChild(element1_);
root_.appendChild(element2_);
root_.appendChild(element3_);
-
+
chapters_ = factory_.createDocument(SA::construct_from_utf8(""), SA::construct_from_utf8(""), 0);
chapters_.appendChild(chapters_.createElement(SA::construct_from_utf8("document")));
chapters_.getFirstChild().appendChild(chapters_.createElement(SA::construct_from_utf8("chapter"))).appendChild(chapters_.createTextNode(SA::construct_from_utf8("one")));
@@ -115,7 +109,7 @@ int main(int argc, char** argv) {
chapters_.getFirstChild().appendChild(chapters_.createElement(SA::construct_from_utf8("chapter"))).appendChild(chapters_.createTextNode(SA::construct_from_utf8("three")));
chapters_.getFirstChild().appendChild(chapters_.createElement(SA::construct_from_utf8("chapter"))).appendChild(chapters_.createTextNode(SA::construct_from_utf8("four")));
chapters_.getFirstChild().appendChild(chapters_.createElement(SA::construct_from_utf8("chapter"))).appendChild(chapters_.createTextNode(SA::construct_from_utf8("five")));
-
+
numbers_ = factory_.createDocument(SA::construct_from_utf8(""), SA::construct_from_utf8(""), 0);
numbers_.appendChild(numbers_.createElement(SA::construct_from_utf8("doc")));
numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("1")));
@@ -131,68 +125,68 @@ int main(int argc, char** argv) {
std::cout << numbers_ << std::endl;
std::cout << chapters_ << std::endl;
-
+
if (false) {
- using namespace Arabica::XPath;
- StringVariableResolver svr;
- svr.setVariable(SA::construct_from_utf8("index"), SA::construct_from_utf8("1"));
-
- parser.setVariableResolver(svr);
- XPathValue<string_type, string_adaptor> result = parser.evaluate(SA::construct_from_utf8("/root/*[@two = $index]"), document_);
- assert(NODE_SET == result.type());
- assert(element2_ == result.asNodeSet()[0]);
-
- parser.resetVariableResolver();
- } // test18
+ using namespace Arabica::XPath;
+ StringVariableResolver svr;
+ svr.setVariable(SA::construct_from_utf8("index"), SA::construct_from_utf8("1"));
+
+ parser.setVariableResolver(svr);
+ XPathValue<string_type, string_adaptor> result = parser.evaluate(SA::construct_from_utf8("/root/*[@two = $index]"), document_);
+ assert(NODE_SET == result.type());
+ assert(element2_ == result.asNodeSet()[0]);
+
+ parser.resetVariableResolver();
+ } // test18
if (false) {
- using namespace Arabica::XPath;
- XPathExpression<string_type, string_adaptor> xpath = parser.compile(SA::construct_from_utf8("root/*[position() = 2]"));
- XPathValue<string_type, string_adaptor> result = xpath.evaluate(document_);
-
- assert(NODE_SET == result.type());
- assert(1 == result.asNodeSet().size());
- Arabica::DOM::Node<string_type, string_adaptor> n = result.asNodeSet()[0];
- assert(element2_ == n);
- } // test19
+ using namespace Arabica::XPath;
+ XPathExpression<string_type, string_adaptor> xpath = parser.compile(SA::construct_from_utf8("root/*[position() = 2]"));
+ XPathValue<string_type, string_adaptor> result = xpath.evaluate(document_);
+
+ assert(NODE_SET == result.type());
+ assert(1 == result.asNodeSet().size());
+ Arabica::DOM::Node<string_type, string_adaptor> n = result.asNodeSet()[0];
+ assert(element2_ == n);
+ } // test19
if (false) {
- using namespace Arabica::XPath;
- Arabica::DOM::DocumentFragment<string_type, string_adaptor> frag = document_.createDocumentFragment();
- frag.appendChild(document_.createElement(SA::construct_from_utf8("foo")));
-
- NodeSetVariableResolver svr;
- NodeSet<string_type, string_adaptor> ns;
- ns.push_back(frag);
- svr.setVariable(SA::construct_from_utf8("fruit"), ns);
- parser.setVariableResolver(svr);
-
- XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("$fruit/foo|/root/child3"), document_);
- assert(NODE_SET == result.type());
- assert(2 == result.asNodeSet().size());
- assert(element3_ == result.asNodeSet()[0]);
- } // testUnion11
+ using namespace Arabica::XPath;
+ Arabica::DOM::DocumentFragment<string_type, string_adaptor> frag = document_.createDocumentFragment();
+ frag.appendChild(document_.createElement(SA::construct_from_utf8("foo")));
+
+ NodeSetVariableResolver svr;
+ NodeSet<string_type, string_adaptor> ns;
+ ns.push_back(frag);
+ svr.setVariable(SA::construct_from_utf8("fruit"), ns);
+ parser.setVariableResolver(svr);
+
+ XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("$fruit/foo|/root/child3"), document_);
+ assert(NODE_SET == result.type());
+ assert(2 == result.asNodeSet().size());
+ assert(element3_ == result.asNodeSet()[0]);
+ } // testUnion11
if (false) {
- using namespace Arabica::XPath;
- XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("local-name(/root)"), document_);
- assert(STRING == result.type());
- assert(SA::construct_from_utf8("root") == result.asString());
- } // testLocalNameFn1
+ using namespace Arabica::XPath;
+ XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("local-name(/root)"), document_);
+ assert(STRING == result.type());
+ assert(SA::construct_from_utf8("root") == result.asString());
+ } // testLocalNameFn1
{
- using namespace Arabica::XPath;
- Arabica::DOM::DocumentFragment<std::string> frag = document_.createDocumentFragment();
- frag.appendChild(document_.createElement("foo"));
-
- NodeSetVariableResolver svr;
- NodeSet<string_type, string_adaptor> ns;
- ns.push_back(frag);
- svr.setVariable("fruit", ns);
- parser.setVariableResolver(svr);
-
- XPathValue<string_type, string_adaptor> result = parser.evaluate(SA::construct_from_utf8("local-name($fruit/foo) = 'foo'"), document_);
+ using namespace Arabica::XPath;
+ Arabica::DOM::DocumentFragment<std::string> frag = document_.createDocumentFragment();
+ frag.appendChild(document_.createElement("foo"));
+
+ NodeSetVariableResolver svr;
+ NodeSet<string_type, string_adaptor> ns;
+ ns.push_back(frag);
+ svr.setVariable("fruit", ns);
+ parser.setVariableResolver(svr);
+
+ XPathValue<string_type, string_adaptor> result = parser.evaluate(SA::construct_from_utf8("local-name($fruit/foo) = 'foo'"), document_);
std::cout << result.asBool() << std::endl;
- }
+ }
} \ No newline at end of file