diff options
23 files changed, 198 insertions, 65 deletions
diff --git a/apps/uscxml-browser.cpp b/apps/uscxml-browser.cpp index bba1bc0..8708e09 100644 --- a/apps/uscxml-browser.cpp +++ b/apps/uscxml-browser.cpp @@ -1,5 +1,6 @@ #include "uscxml/config.h" #include "uscxml/Interpreter.h" +#include "uscxml/DOMUtils.h" #include "uscxml/debug/SCXMLDotWriter.h" #include <glog/logging.h> diff --git a/src/uscxml/NameSpacingParser.cpp b/src/uscxml/DOMUtils.cpp index beaae95..d521b49 100644 --- a/src/uscxml/NameSpacingParser.cpp +++ b/src/uscxml/DOMUtils.cpp @@ -18,12 +18,55 @@ */ #include <uscxml/Common.h> -#include "NameSpacingParser.h" +#include "DOMUtils.h" +#include <uscxml/Convenience.h> #include <glog/logging.h> #include <SAX/helpers/InputSourceResolver.hpp> namespace uscxml { +std::string DOMUtils::xPathForNode(const Arabica::DOM::Node<std::string>& node) { + std::string xPath; + + if (!node || node.getNodeType() != Arabica::DOM::Node_base::ELEMENT_NODE) + return xPath; + + Arabica::DOM::Node<std::string> curr = node; + while(curr) { + switch (curr.getNodeType()) { + case Arabica::DOM::Node_base::ELEMENT_NODE: { + if (HAS_ATTR(curr, "id")) { + // we assume ids to be unique and return immediately + xPath.insert(0, "//" + TAGNAME(curr) + "[@id=\"" + ATTR(curr, "id") + "\"]"); + return xPath; + } else { + // check previous siblings to count our index + Arabica::DOM::Node<std::string> sibling = curr.getPreviousSibling(); + int index = 1; + while(sibling) { + if (sibling.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE) { + if (iequals(TAGNAME(sibling), TAGNAME(curr))) { + index++; + } + } + sibling = sibling.getPreviousSibling(); + } + xPath.insert(0, "/" + TAGNAME(curr) + "[" + toStr(index) + "]"); + } + break; + } + case Arabica::DOM::Node_base::DOCUMENT_NODE: + return xPath; + default: + LOG(ERROR) << "Only nodes of type element supported for now"; + return ""; + break; + } + curr = curr.getParentNode(); + } + return xPath; +} + NameSpacingParser NameSpacingParser::fromXML(const std::string& xml) { std::stringstream* ss = new std::stringstream(); (*ss) << xml; diff --git a/src/uscxml/NameSpacingParser.h b/src/uscxml/DOMUtils.h index 88933c6..31e7df0 100644 --- a/src/uscxml/NameSpacingParser.h +++ b/src/uscxml/DOMUtils.h @@ -17,15 +17,26 @@ * @endcond */ -#ifndef NAMESPACINGPARSER_H_1S91TNPM -#define NAMESPACINGPARSER_H_1S91TNPM +#ifndef DOMUTILS_H_WK0WAEA7 +#define DOMUTILS_H_WK0WAEA7 #include "uscxml/Common.h" #include <DOM/SAX2DOM/SAX2DOM.hpp> #include <SAX/helpers/CatchErrorHandler.hpp> +#define TAGNAME(elem) ((Arabica::DOM::Element<std::string>)elem).getTagName() +#define LOCALNAME(elem) ((Arabica::DOM::Element<std::string>)elem).getLocalName() +#define ATTR(elem, attr) ((Arabica::DOM::Element<std::string>)elem).getAttribute(attr) +#define ATTR_NODE(elem, attr) ((Arabica::DOM::Element<std::string>)elem).getAttributeNode(attr) +#define HAS_ATTR(elem, attr) ((Arabica::DOM::Element<std::string>)elem).hasAttribute(attr) + namespace uscxml { +class USCXML_API DOMUtils { +public: + static std::string xPathForNode(const Arabica::DOM::Node<std::string>& node); +}; + class ScriptEntityResolver : public Arabica::SAX::EntityResolver<std::string> { virtual InputSourceT resolveEntity(const std::string& publicId, const std::string& systemId) { Arabica::SAX::InputSource<std::string> is; @@ -58,4 +69,5 @@ private: } -#endif /* end of include guard: NAMESPACINGPARSER_H_1S91TNPM */ + +#endif /* end of include guard: DOMUTILS_H_WK0WAEA7 */ diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index bb54c6f..b91991b 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -22,7 +22,7 @@ #include "uscxml/Interpreter.h" #include "uscxml/URL.h" #include "uscxml/UUID.h" -#include "uscxml/NameSpacingParser.h" +#include "uscxml/DOMUtils.h" #include "uscxml/debug/SCXMLDotWriter.h" #include "uscxml/plugins/invoker/http/HTTPServletInvoker.h" @@ -56,6 +56,19 @@ catch (Event e) {\ }\ } +#define CATCH_AND_DISTRIBUTE2(msg, node) \ +catch (Event e) {\ + LOG(ERROR) << msg << " " << DOMUtils::xPathForNode(node) << ":" << std::endl << e << std::endl;\ + if (rethrow) {\ + throw(e);\ + } else {\ + e.name = "error.execution";\ + e.eventType = Event::PLATFORM;\ + e.dom = node;\ + receiveInternal(e);\ + }\ +} + namespace uscxml { using namespace Arabica::XPath; @@ -245,7 +258,8 @@ InterpreterImpl::InterpreterImpl() { _httpServlet = NULL; _factory = NULL; _capabilities = CAN_BASIC_HTTP | CAN_GENERIC_HTTP; - + _domEventListener._interpreter = this; + #ifdef _WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); @@ -458,6 +472,12 @@ void InterpreterImpl::init() { _sendQueue = new DelayedEventQueue(); _sendQueue->start(); + // register for dom events to manage cached states + Arabica::DOM::Events::EventTarget<std::string> eventTarget(_scxml); + eventTarget.addEventListener("DOMNodeInserted", _domEventListener, true); + eventTarget.addEventListener("DOMNodeRemoved", _domEventListener, true); + eventTarget.addEventListener("DOMSubtreeModified", _domEventListener, true); + if (_factory == NULL) _factory = Factory::getInstance(); @@ -491,7 +511,7 @@ void InterpreterImpl::initializeData(const Element<std::string>& data) { try { _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; + LOG(ERROR) << "Syntax error when initializing data " << DOMUtils::xPathForNode(data) << " from parameters:" << std::endl << e << std::endl; receiveInternal(e); } return; @@ -500,7 +520,7 @@ void InterpreterImpl::initializeData(const Element<std::string>& data) { try { _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; + LOG(ERROR) << "Syntax error when initializing data " << DOMUtils::xPathForNode(data) << " from namelist:" << std::endl << e << std::endl; receiveInternal(e); } return; @@ -512,7 +532,7 @@ void InterpreterImpl::initializeData(const Element<std::string>& data) { processDOMorText(data, dom, text); _dataModel.init(data, dom, text); } catch (Event e) { - LOG(ERROR) << "Syntax error when initializing data:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error when initializing data " << DOMUtils::xPathForNode(data) << ":" << std::endl << e << std::endl; receiveInternal(e); } } @@ -618,6 +638,7 @@ void InterpreterImpl::internalDoneSend(const Arabica::DOM::Node<std::string>& st event.content =_dataModel.evalAsString(expr); } catch (Event e) { e.name = "error.execution"; + e.dom = contents[0]; receiveInternal(e); } } @@ -751,34 +772,35 @@ void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& el void InterpreterImpl::processParamChilds(const Arabica::DOM::Node<std::string>& element, std::multimap<std::string, Data>& params) { NodeSet<std::string> paramElems = filterChildElements(_xmlNSPrefix + "param", element); - try { for (int i = 0; i < paramElems.size(); i++) { - if (!HAS_ATTR(paramElems[i], "name")) { - LOG(ERROR) << "param element is missing name attribute"; - continue; - } - Data paramValue; - if (HAS_ATTR(paramElems[i], "expr") && _dataModel) { - paramValue = _dataModel.getStringAsData(ATTR(paramElems[i], "expr")); - } else if(HAS_ATTR(paramElems[i], "location") && _dataModel) { - paramValue = _dataModel.getStringAsData(ATTR(paramElems[i], "location")); - } else { - LOG(ERROR) << "param element is missing expr or location or no datamodel is specified"; - continue; + try { + if (!HAS_ATTR(paramElems[i], "name")) { + LOG(ERROR) << "param element is missing name attribute"; + continue; + } + Data paramValue; + if (HAS_ATTR(paramElems[i], "expr") && _dataModel) { + paramValue = _dataModel.getStringAsData(ATTR(paramElems[i], "expr")); + } else if(HAS_ATTR(paramElems[i], "location") && _dataModel) { + paramValue = _dataModel.getStringAsData(ATTR(paramElems[i], "location")); + } else { + LOG(ERROR) << "param element is missing expr or location or no datamodel is specified"; + continue; + } + std::string paramKey = ATTR(paramElems[i], "name"); + params.insert(std::make_pair(paramKey, paramValue)); + } catch(Event e) { + LOG(ERROR) << "Syntax error while processing params " << DOMUtils::xPathForNode(paramElems[i]) << ":" << std::endl << e << std::endl; + // test 343 + std::multimap<std::string, Data>::iterator paramIter = params.begin(); + while(paramIter != params.end()) { + params.erase(paramIter++); + } + e.name = "error.execution"; + receiveInternal(e); + break; } - std::string paramKey = ATTR(paramElems[i], "name"); - params.insert(std::make_pair(paramKey, paramValue)); - } - } catch(Event e) { - LOG(ERROR) << "Syntax error while processing params:" << std::endl << e << std::endl; - // test 343 - std::multimap<std::string, Data>::iterator paramIter = params.begin(); - while(paramIter != params.end()) { - params.erase(paramIter++); } - e.name = "error.execution"; - receiveInternal(e); - } } void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { @@ -793,7 +815,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { sendReq.name = ATTR(element, "event"); } } catch (Event e) { - LOG(ERROR) << "Syntax error in send element eventexpr:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in send element eventexpr " << DOMUtils::xPathForNode(element) << ":" << std::endl << e << std::endl; return; } try { @@ -804,7 +826,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { sendReq.target = ATTR(element, "target"); } } catch (Event e) { - LOG(ERROR) << "Syntax error in send element targetexpr:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(element) << " targetexpr:" << std::endl << e << std::endl; return; } try { @@ -815,7 +837,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { sendReq.type = ATTR(element, "type"); } } catch (Event e) { - LOG(ERROR) << "Syntax error in send element typeexpr:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(element) << " typeexpr:" << std::endl << e << std::endl; return; } try { @@ -850,7 +872,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { } } } catch (Event e) { - LOG(ERROR) << "Syntax error in send element idlocation:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(element) << " idlocation:" << std::endl << e << std::endl; return; } @@ -877,7 +899,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { } } } catch (Event e) { - LOG(ERROR) << "Syntax error in send element delayexpr:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(element) << " delayexpr:" << std::endl << e << std::endl; return; } @@ -896,7 +918,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { } } } catch (Event e) { - LOG(ERROR) << "Syntax error in send element namelist:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(element) << " namelist:" << std::endl << e << std::endl; return; } @@ -904,14 +926,14 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { // params processParamChilds(element, sendReq.params); } catch (Event e) { - LOG(ERROR) << "Syntax error in send element param expr:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(element) << " param expr:" << std::endl << e << std::endl; return; } try { // content NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", element); if (contents.size() > 1) - LOG(ERROR) << "Only a single content element is allowed for send elements - using first one"; + LOG(ERROR) << "Only a single content element is allowed for send elements " << DOMUtils::xPathForNode(element) << " - using first one"; if (contents.size() > 0) { std::string expr; processContentElement(contents[0], sendReq.dom, sendReq.content, expr); @@ -927,7 +949,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { } } } catch (Event e) { - LOG(ERROR) << "Syntax error in send element content:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(element) << " content:" << std::endl << e << std::endl; return; } @@ -1058,6 +1080,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { invokeReq.data =_dataModel.getStringAsData(expr); } catch (Event e) { e.name = "error.execution"; + e.dom = contents[0]; receiveInternal(e); } } else if (invokeReq.content.length() > 0) { @@ -1066,7 +1089,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { } } catch (Event e) { - LOG(ERROR) << "Syntax error in send element content:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(element) << " content:" << std::endl << e << std::endl; return; } @@ -1110,7 +1133,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { } } catch (Event e) { - LOG(ERROR) << "Syntax error in invoke element:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in invoke element " << DOMUtils::xPathForNode(element) << ":" << std::endl << e << std::endl; } } @@ -1195,7 +1218,7 @@ bool InterpreterImpl::hasConditionMatch(const Arabica::DOM::Node<std::string>& c try { return _dataModel.evalAsBool(ATTR_NODE(conditional, "cond"), ATTR(conditional, "cond")); } catch (Event e) { - LOG(ERROR) << "Syntax error in cond attribute of " << TAGNAME(conditional) << " element:" << std::endl << e << std::endl; + LOG(ERROR) << "Syntax error in cond attribute of " << TAGNAME(conditional) << " element " << DOMUtils::xPathForNode(conditional) << ":" << std::endl << e << std::endl; e.name = "error.execution"; receiveInternal(e); return false; @@ -1212,7 +1235,7 @@ void InterpreterImpl::executeContent(const NodeList<std::string>& content, bool try { executeContent(content.item(i), true); } - CATCH_AND_DISTRIBUTE("Error when executing content"); + CATCH_AND_DISTRIBUTE2("Error when executing content", content.item(i)); } } @@ -1223,7 +1246,7 @@ void InterpreterImpl::executeContent(const NodeSet<std::string>& content, bool r try { executeContent(content[i], true); } - CATCH_AND_DISTRIBUTE("Error when executing content"); + CATCH_AND_DISTRIBUTE2("Error when executing content", content[i]); } } @@ -1294,7 +1317,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont try { iterations = _dataModel.getLength(array); } - CATCH_AND_DISTRIBUTE("Syntax error in array attribute of foreach element:") + CATCH_AND_DISTRIBUTE2("Syntax error in array attribute of foreach element", content) try { _dataModel.pushContext(); // copy old and enter new context // if (!_dataModel.isDeclared(item)) { @@ -1308,7 +1331,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont } _dataModel.popContext(); // leave stacked context } - CATCH_AND_DISTRIBUTE("Syntax error in foreach element:") + CATCH_AND_DISTRIBUTE2("Syntax error in foreach element", content) } else { LOG(ERROR) << "Expected array and item attributes with foreach element!" << std::endl; } @@ -1322,7 +1345,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont try { std::cout << _dataModel.evalAsString(logElem.getAttribute("expr")) << std::endl; } - CATCH_AND_DISTRIBUTE("Syntax error in expr attribute of log element:") + CATCH_AND_DISTRIBUTE2("Syntax error in expr attribute of log element", content) } else { if (logElem.hasAttribute("label")) std::cout << std::endl; @@ -1342,7 +1365,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont _dataModel.assign(Element<std::string>(content), dom, text); } } - CATCH_AND_DISTRIBUTE("Syntax error in attributes of assign element:") + CATCH_AND_DISTRIBUTE2("Syntax error in attributes of assign element", content) } } else if (iequals(TAGNAME(content), _xmlNSPrefix + "validate")) { // --- VALIDATE -------------------------- @@ -1394,7 +1417,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont try { _dataModel.eval((Element<std::string>)content, scriptContent); } - CATCH_AND_DISTRIBUTE("Syntax error while executing script element") + CATCH_AND_DISTRIBUTE2("Syntax error while executing script element", content) } } } @@ -1404,7 +1427,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont try { send(content); } - CATCH_AND_DISTRIBUTE("Error while sending content") + CATCH_AND_DISTRIBUTE2("Error while sending content", content) } else if (iequals(TAGNAME(content), _xmlNSPrefix + "cancel")) { // --- CANCEL -------------------------- std::string sendId; @@ -1420,7 +1443,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont _sendQueue->cancelEvent(sendId); } - CATCH_AND_DISTRIBUTE("Syntax error while executing cancel element") + CATCH_AND_DISTRIBUTE2("Syntax error while executing cancel element", content) } else if (iequals(TAGNAME(content), _xmlNSPrefix + "invoke")) { // --- INVOKE -------------------------- } else { @@ -2090,6 +2113,19 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) { return true; } +void InterpreterImpl::DOMEventListener::handleEvent(Arabica::DOM::Events::Event<std::string>& event) { + // remove modified states from cache + if (event.getType().compare("DOMAttrModified") == 0) // we do not care about attributes + return; + Node<std::string> target = Arabica::DOM::Node<std::string>(event.getTarget()); + NodeSet<std::string> childs = Interpreter::filterChildElements(_interpreter->_xmlNSPrefix + "state", target); + for (int i = 0; i < childs.size(); i++) { + if (HAS_ATTR(childs[i], "id")) { + _interpreter->_cachedStates.erase(ATTR(childs[i], "id")); + } + } +} + void InterpreterImpl::dump() { if (!_document) return; diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index ac26457..008de6f 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -37,6 +37,8 @@ #include <DOM/SAX2DOM/SAX2DOM.hpp> #include <SAX/helpers/CatchErrorHandler.hpp> +#include <DOM/Events/EventTarget.hpp> +#include <DOM/Events/EventListener.hpp> #include "uscxml/concurrency/tinythread.h" #include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" @@ -130,6 +132,12 @@ public: LATE = 1 }; + class DOMEventListener : public Arabica::DOM::Events::EventListener<std::string> { + public: + void handleEvent(Arabica::DOM::Events::Event<std::string>& event); + InterpreterImpl* _interpreter; + }; + virtual ~InterpreterImpl(); void start(); @@ -339,6 +347,8 @@ protected: uscxml::concurrency::BlockingQueue<SendRequest>* _parentQueue; DelayedEventQueue* _sendQueue; + DOMEventListener _domEventListener; + Event _currEvent; Factory* _factory; InterpreterServlet* _httpServlet; diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp index fd39324..c79e08a 100644 --- a/src/uscxml/Message.cpp +++ b/src/uscxml/Message.cpp @@ -21,7 +21,7 @@ #include "uscxml/Common.h" #include "uscxml/Message.h" -//#include "uscxml/Interpreter.h" +#include "uscxml/DOMUtils.h" #include <DOM/SAX2DOM/SAX2DOM.hpp> #include <SAX/helpers/CatchErrorHandler.hpp> #include <glog/logging.h> @@ -509,7 +509,7 @@ std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq) { indent += " "; } - os << indent<< "SendReq" << std::endl; + os << indent << "SendReq" << std::endl; if (sendReq.target.size() > 0) os << indent << " target: " << sendReq.target << std::endl; @@ -628,6 +628,12 @@ std::string Data::toJSON(const Data& data) { } else { os << data.atom; } + } else if (data.node) { + if (data.type == Data::VERBATIM) { + os << ""; + } else { + os << data.atom; + } } else { os << "undefined"; } diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h index 4aba5ed..1964f1c 100644 --- a/src/uscxml/Message.h +++ b/src/uscxml/Message.h @@ -40,12 +40,6 @@ #include "uscxml/util/MD5.h" #include "uscxml/util/Base64.h" -#define TAGNAME(elem) ((Arabica::DOM::Element<std::string>)elem).getTagName() -#define LOCALNAME(elem) ((Arabica::DOM::Element<std::string>)elem).getLocalName() -#define ATTR(elem, attr) ((Arabica::DOM::Element<std::string>)elem).getAttribute(attr) -#define ATTR_NODE(elem, attr) ((Arabica::DOM::Element<std::string>)elem).getAttributeNode(attr) -#define HAS_ATTR(elem, attr) ((Arabica::DOM::Element<std::string>)elem).hasAttribute(attr) - namespace uscxml { class USCXML_API Blob { diff --git a/src/uscxml/debug/SCXMLDotWriter.cpp b/src/uscxml/debug/SCXMLDotWriter.cpp index e2d21a7..07e7b9a 100644 --- a/src/uscxml/debug/SCXMLDotWriter.cpp +++ b/src/uscxml/debug/SCXMLDotWriter.cpp @@ -19,6 +19,7 @@ #include "uscxml/Common.h" #include "SCXMLDotWriter.h" +#include "uscxml/DOMUtils.h" #include <boost/algorithm/string.hpp> // replace_all #include <iomanip> diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index 96b6ecb..8663cfc 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -21,6 +21,7 @@ #include <glog/logging.h> #include "uscxml/UUID.h" +#include "uscxml/DOMUtils.h" namespace uscxml { diff --git a/src/uscxml/interpreter/InterpreterDraft7.cpp b/src/uscxml/interpreter/InterpreterDraft7.cpp index cc54bc0..cb0ca38 100644 --- a/src/uscxml/interpreter/InterpreterDraft7.cpp +++ b/src/uscxml/interpreter/InterpreterDraft7.cpp @@ -22,6 +22,7 @@ #include <glog/logging.h> #include "uscxml/UUID.h" +#include "uscxml/DOMUtils.h" namespace uscxml { diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index dbe4be5..f17bc62 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -40,6 +40,7 @@ #include "dom/JSCDataView.h" #include "uscxml/Message.h" +#include "uscxml/DOMUtils.h" #include <glog/logging.h> #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index 1037802..e7c0c72 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -41,6 +41,7 @@ #include "dom/V8DataView.h" #include "uscxml/Message.h" +#include "uscxml/DOMUtils.h" #include <glog/logging.h> #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp index 05072df..1938b0c 100644 --- a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp +++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp @@ -21,6 +21,7 @@ #include "uscxml/Common.h" #include "NULLDataModel.h" +#include "uscxml/DOMUtils.h" #include "uscxml/Message.h" #include <glog/logging.h> diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp index 02352fc..9a0a831 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp @@ -22,6 +22,7 @@ #include "uscxml/Common.h" #include "uscxml/config.h" #include "SWIDataModel.h" +#include "uscxml/DOMUtils.h" #include "uscxml/Message.h" #include <glog/logging.h> diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp index e81883a..3a99df8 100644 --- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp +++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp @@ -21,6 +21,7 @@ #include "XPathDataModel.h" #include "uscxml/Message.h" +#include "uscxml/DOMUtils.h" #include <glog/logging.h> #include <boost/algorithm/string.hpp> diff --git a/src/uscxml/plugins/element/fetch/FetchElement.cpp b/src/uscxml/plugins/element/fetch/FetchElement.cpp index 37dd6c0..b40f487 100644 --- a/src/uscxml/plugins/element/fetch/FetchElement.cpp +++ b/src/uscxml/plugins/element/fetch/FetchElement.cpp @@ -20,6 +20,7 @@ #include <boost/algorithm/string.hpp> #include "FetchElement.h" +#include "uscxml/DOMUtils.h" #include <glog/logging.h> #include <event2/http.h> diff --git a/src/uscxml/plugins/element/file/FileElement.cpp b/src/uscxml/plugins/element/file/FileElement.cpp index 346c75d..3a8574d 100644 --- a/src/uscxml/plugins/element/file/FileElement.cpp +++ b/src/uscxml/plugins/element/file/FileElement.cpp @@ -23,7 +23,7 @@ #include <vector> #include <boost/algorithm/string.hpp> -#include "uscxml/NameSpacingParser.h" +#include "uscxml/DOMUtils.h" #ifdef BUILD_AS_PLUGINS #include <Pluma/Connector.hpp> diff --git a/src/uscxml/plugins/element/postpone/PostponeElement.cpp b/src/uscxml/plugins/element/postpone/PostponeElement.cpp index f9ddd5f..7a18b38 100644 --- a/src/uscxml/plugins/element/postpone/PostponeElement.cpp +++ b/src/uscxml/plugins/element/postpone/PostponeElement.cpp @@ -21,6 +21,7 @@ #include "PostponeElement.h" #include "uscxml/plugins/invoker/http/HTTPServletInvoker.h" +#include "uscxml/DOMUtils.h" #include <glog/logging.h> #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/element/respond/RespondElement.cpp b/src/uscxml/plugins/element/respond/RespondElement.cpp index 2b8d02d..a88d9c6 100644 --- a/src/uscxml/plugins/element/respond/RespondElement.cpp +++ b/src/uscxml/plugins/element/respond/RespondElement.cpp @@ -19,6 +19,7 @@ #include "RespondElement.h" #include "uscxml/plugins/invoker/http/HTTPServletInvoker.h" +#include "uscxml/DOMUtils.h" #include <glog/logging.h> #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp index cd690ff..9e435d2 100644 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp @@ -22,6 +22,7 @@ #include "OSGInvoker.h" #include "uscxml/URL.h" #include "uscxml/UUID.h" +#include "uscxml/DOMUtils.h" #include <glog/logging.h> #include <osg/Shape> diff --git a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp index 04cb143..c0a0a07 100644 --- a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp @@ -22,6 +22,7 @@ #include <uscxml/config.h> #include "XHTMLInvoker.h" #include <glog/logging.h> +#include "uscxml/DOMUtils.h" #include <uscxml/plugins/ioprocessor/comet/CometIOProcessor.h> #include <DOM/io/Stream.hpp> diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp index 15f347c..6065740 100644 --- a/src/uscxml/server/HTTPServer.cpp +++ b/src/uscxml/server/HTTPServer.cpp @@ -25,7 +25,7 @@ #endif #include "uscxml/server/HTTPServer.h" -#include "uscxml/NameSpacingParser.h" +#include "uscxml/DOMUtils.h" #include <string> #include <iostream> diff --git a/test/src/test-arabica-xpath.cpp b/test/src/test-arabica-xpath.cpp index fe457f4..ce389fa 100644 --- a/test/src/test-arabica-xpath.cpp +++ b/test/src/test-arabica-xpath.cpp @@ -5,6 +5,7 @@ #include <DOM/io/Stream.hpp> #include <iostream> #include <string> +#include "uscxml/DOMUtils.h" #define string_type std::string #define string_adaptor Arabica::default_string_adaptor<std::string> @@ -127,6 +128,23 @@ int main(int argc, char** argv) { std::cout << numbers_ << std::endl; std::cout << chapters_ << std::endl; + if (true) { + using namespace Arabica::XPath; + using namespace Arabica::DOM; + XPathValue<string_type, string_adaptor> result = parser.evaluate(SA::construct_from_utf8("//*"), document_); + for(int i = 0; i < result.asNodeSet().size(); i++) { + Node<string_type, string_adaptor> node = result.asNodeSet()[i]; + std::string xpathExpr = uscxml::DOMUtils::xPathForNode(node); + if (xpathExpr.size()) { + XPathValue<string_type, string_adaptor> innerResult = parser.evaluate(xpathExpr, document_); + assert(innerResult.asNodeSet().size() > 0); + assert(innerResult.asNodeSet().size() == 1); + assert(innerResult.asNodeSet()[0] == node); + } else { + assert(node.getNodeType() != Node_base::ELEMENT_NODE); + } + } + } if (false) { using namespace Arabica::XPath; |