diff options
Diffstat (limited to 'src/uscxml')
31 files changed, 316 insertions, 185 deletions
diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp index bc23e53..1494dff 100644 --- a/src/uscxml/Factory.cpp +++ b/src/uscxml/Factory.cpp @@ -352,7 +352,9 @@ boost::shared_ptr<InvokerImpl> Factory::createInvoker(const std::string& type, I if (_invokerAliases.find(type) != _invokerAliases.end()) { std::string canonicalName = _invokerAliases[type]; if (_invokers.find(canonicalName) != _invokers.end()) { - return _invokers[canonicalName]->create(interpreter); + boost::shared_ptr<InvokerImpl> invoker = _invokers[canonicalName]->create(interpreter); + invoker->setInterpreter(interpreter); + return invoker; } } @@ -372,7 +374,9 @@ boost::shared_ptr<DataModelImpl> Factory::createDataModel(const std::string& typ if (_dataModelAliases.find(type) != _dataModelAliases.end()) { std::string canonicalName = _dataModelAliases[type]; if (_dataModels.find(canonicalName) != _dataModels.end()) { - return _dataModels[canonicalName]->create(interpreter); + boost::shared_ptr<DataModelImpl> dataModel = _dataModels[canonicalName]->create(interpreter); + dataModel->setInterpreter(interpreter); + return dataModel; } } @@ -391,7 +395,9 @@ boost::shared_ptr<IOProcessorImpl> Factory::createIOProcessor(const std::string& if (_ioProcessorAliases.find(type) != _ioProcessorAliases.end()) { std::string canonicalName = _ioProcessorAliases[type]; if (_ioProcessors.find(canonicalName) != _ioProcessors.end()) { - return _ioProcessors[canonicalName]->create(interpreter); + boost::shared_ptr<IOProcessorImpl> ioProc = _ioProcessors[canonicalName]->create(interpreter); + ioProc->setInterpreter(interpreter); + return ioProc; } } @@ -399,7 +405,7 @@ boost::shared_ptr<IOProcessorImpl> Factory::createIOProcessor(const std::string& if (_parentFactory) { return _parentFactory->createIOProcessor(type, interpreter); } else { - LOG(ERROR) << "No " << type << " Datamodel known"; + LOG(ERROR) << "No " << type << " IOProcessor known"; } return boost::shared_ptr<IOProcessorImpl>(); @@ -409,7 +415,8 @@ boost::shared_ptr<ExecutableContentImpl> Factory::createExecutableContent(const // do we have this type in this factory? std::string actualNameSpace = (nameSpace.length() == 0 ? "http://www.w3.org/2005/07/scxml" : nameSpace); if (_executableContent.find(std::make_pair(localName, actualNameSpace)) != _executableContent.end()) { - return _executableContent[std::make_pair(localName, actualNameSpace)]->create(interpreter); + boost::shared_ptr<ExecutableContentImpl> execContent = _executableContent[std::make_pair(localName, actualNameSpace)]->create(interpreter); + execContent->setInterpreter(interpreter); } // lookup in parent factory diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h index 0432f34..b815712 100644 --- a/src/uscxml/Factory.h +++ b/src/uscxml/Factory.h @@ -52,7 +52,9 @@ public: } virtual std::string getLocalName() = 0; ///< The name of the element. - virtual std::string getNamespace() = 0; ///< The namespace of the element. + virtual std::string getNamespace() { + return "http://www.w3.org/2005/07/scxml"; ///< The namespace of the element. + } virtual void enterElement(const Arabica::DOM::Node<std::string>& node) = 0; ///< Invoked when entering the element as part of evaluating executable content. virtual void exitElement(const Arabica::DOM::Node<std::string>& node) = 0; ///< Invoked when exiting the element as part of evaluating executable content. virtual bool processChildren() = 0; ///< Whether or not the interpreter should process this elements children. @@ -283,15 +285,19 @@ public: virtual bool isDeclared(const std::string& expr) = 0; virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Document<std::string>& doc, + const Arabica::DOM::Node<std::string>& node, 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 Arabica::DOM::Node<std::string>& node, const std::string& content) = 0; virtual void init(const std::string& location, const Data& data) = 0; + virtual void setInterpreter(InterpreterImpl* interpreter) { + _interpreter = interpreter; + } + // we need it public for various static functions InterpreterImpl* _interpreter; }; @@ -358,18 +364,18 @@ public: } virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Document<std::string>& doc, + const Arabica::DOM::Node<std::string>& node, const std::string& content) { - return _impl->assign(assignElem, doc, content); + return _impl->assign(assignElem, node, content); } virtual void assign(const std::string& location, const Data& data) { return _impl->assign(location, data); } virtual void init(const Arabica::DOM::Element<std::string>& dataElem, - const Arabica::DOM::Document<std::string>& doc, + const Arabica::DOM::Node<std::string>& node, const std::string& content) { - return _impl->init(dataElem, doc, content); + return _impl->init(dataElem, node, content); } virtual void init(const std::string& location, const Data& data) { return _impl->init(location, data); @@ -383,6 +389,10 @@ public: return _impl->replaceExpressions(content); } + virtual void setInterpreter(InterpreterImpl* interpreter) { + _impl->setInterpreter(interpreter); + } + protected: boost::shared_ptr<DataModelImpl> _impl; }; diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 6b17d94..4015026 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -174,7 +174,7 @@ void InterpreterImpl::setNameSpaceInfo(const std::map<std::string, std::string> if (boost::iequals(uri, "http://www.w3.org/2005/07/scxml")) { _nsURL = uri; if (prefix.size() == 0) { - LOG(INFO) << "Mapped default namespace to 'scxml:'"; +// LOG(INFO) << "Mapped default namespace to 'scxml:'"; _xpathPrefix = "scxml:"; _nsContext.addNamespaceDeclaration(uri, "scxml"); _nsToPrefix[uri] = "scxml"; @@ -203,11 +203,12 @@ void InterpreterImpl::setName(const std::string& name) { InterpreterImpl::~InterpreterImpl() { _running = false; - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); +// tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); if (_thread) { // unblock event queue Event event; - _externalQueue.push(event); + event.name = "unblock.and.die"; + receive(event); _thread->join(); delete(_thread); } @@ -327,7 +328,7 @@ void InterpreterImpl::initializeData(const Element<std::string>& data) { } try { - Arabica::DOM::Document<std::string> dom; + Arabica::DOM::Node<std::string> dom; std::string text; processDOMorText(data, dom, text); _dataModel.init(data, dom, text); @@ -401,6 +402,7 @@ void InterpreterImpl::normalize(Arabica::DOM::Element<std::string>& scxml) { void InterpreterImpl::receiveInternal(const Event& event) { std::cout << _name << " receiveInternal: " << event.name << std::endl; _internalQueue.push_back(event); +// _condVar.notify_all(); } void InterpreterImpl::receive(const Event& event, bool toFront) { @@ -410,6 +412,7 @@ void InterpreterImpl::receive(const Event& event, bool toFront) { } else { _externalQueue.push(event); } + _condVar.notify_all(); } void InterpreterImpl::internalDoneSend(const Arabica::DOM::Node<std::string>& state) { @@ -448,7 +451,7 @@ 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, + Arabica::DOM::Node<std::string>& dom, std::string& text, std::string& expr) { if (HAS_ATTR(content, "expr")) { @@ -460,16 +463,16 @@ void InterpreterImpl::processContentElement(const Arabica::DOM::Node<std::string } } -void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& node, - Arabica::DOM::Document<std::string>& dom, +void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& element, + Arabica::DOM::Node<std::string>& dom, std::string& text) { // do we need to download? - if (HAS_ATTR(node, "src") || - (HAS_ATTR(node, "srcexpr") && _dataModel)) { + if (HAS_ATTR(element, "src") || + (HAS_ATTR(element, "srcexpr") && _dataModel)) { std::stringstream srcContent; - URL sourceURL(HAS_ATTR(node, "srcexpr") ? _dataModel.evalAsString(ATTR(node, "srcexpr")) : ATTR(node, "src")); + URL sourceURL(HAS_ATTR(element, "srcexpr") ? _dataModel.evalAsString(ATTR(element, "srcexpr")) : ATTR(element, "src")); if (!sourceURL.toAbsolute(_baseURI)) { - LOG(ERROR) << LOCALNAME(node) << " element has relative src or srcexpr URI with no baseURI set."; + LOG(ERROR) << LOCALNAME(element) << " element has relative src or srcexpr URI with no baseURI set."; return; } if (_cachedURLs.find(sourceURL.asString()) != _cachedURLs.end() && false) { @@ -477,14 +480,14 @@ void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& no } else { srcContent << sourceURL; if (sourceURL.downloadFailed()) { - LOG(ERROR) << LOCALNAME(node) << " source cannot be downloaded"; + LOG(ERROR) << LOCALNAME(element) << " 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; + NameSpacingParser parser; std::stringstream* ss = new std::stringstream(); (*ss) << srcContent.str(); std::auto_ptr<std::istream> ssPtr(ss); @@ -494,45 +497,68 @@ void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& no // parser.setFeature(Arabica::SAX::FeatureNames<std::string>().external_general, true); if (parser.parse(inputSource) && parser.getDocument()) { - dom = parser.getDocument(); - //std::cout << dom; - Node<std::string> content = dom.getDocumentElement(); + Document<std::string> doc = parser.getDocument(); + dom = doc.getDocumentElement(); +#if 0 + Node<std::string> content = doc.getDocumentElement(); assert(content.getNodeType() == Node_base::ELEMENT_NODE); - Node<std::string> container = dom.createElement("container"); + Node<std::string> container = doc.createElement("container"); dom.replaceChild(container, content); container.appendChild(content); // std::cout << dom << std::endl; +#endif return; } else { + if (parser.errorsReported()) { + LOG(ERROR) << parser.errors(); + } text = srcContent.str(); return; } } } - if (!node.hasChildNodes()) + if (!element.hasChildNodes()) return; - Node<std::string> child = node.getFirstChild(); - while(child) { - if (child.getNodeType() == Node_base::TEXT_NODE || child.getNodeType() == Node_base::CDATA_SECTION_NODE) { + /** + * Figure out whether the given element contains text, has one child or many childs + */ + bool hasTextContent = false; + bool hasOneChild = false; + Node<std::string> theOneChild; + bool hasManyChilds = false; + + Node<std::string> child = element.getFirstChild(); + while (child) { +// std::cout << child.getNodeType() << std::endl; + if (child.getNodeType() == Node_base::TEXT_NODE || + child.getNodeType() == Node_base::CDATA_SECTION_NODE) { std::string trimmed = child.getNodeValue(); boost::trim(trimmed); - if (trimmed.length() > 0) + if (trimmed.length() > 0) { + hasTextContent = true; + } + } else { + if (hasOneChild) { + hasManyChilds = true; + hasOneChild = false; break; - } - if (child.getNodeType() == Node_base::ELEMENT_NODE) { - break; + } + hasOneChild = true; + theOneChild = child; } 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); - // we need to import the parent - to support xpath test150 - Node<std::string> newNode = dom.importNode(child.getParentNode(), true); - dom.appendChild(newNode); - } else if(child && (child.getNodeType() == Node_base::TEXT_NODE || child.getNodeType() == Node_base::CDATA_SECTION_NODE)) { + + if (hasOneChild) { + // if we have a single child, it will be the content of the dom + dom = theOneChild; + } else if (hasManyChilds) { + // if we have multiple childs + dom = element; + } else if(hasTextContent) { + child = element.getFirstChild(); while(child) { if ((child.getNodeType() == Node_base::TEXT_NODE || child.getNodeType() == Node_base::CDATA_SECTION_NODE)) { text += child.getNodeValue(); @@ -540,7 +566,7 @@ void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& no child = child.getNextSibling(); } } else { - LOG(ERROR) << LOCALNAME(node) << " has neither text nor element children."; + LOG(ERROR) << LOCALNAME(element) << " has neither text nor element children."; } } @@ -1123,7 +1149,7 @@ 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 { - Document<std::string> dom; + Node<std::string> dom; std::string text; processDOMorText(content, dom, text); _dataModel.assign(Element<std::string>(content), dom, text); @@ -1188,7 +1214,10 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont } } else if (boost::iequals(TAGNAME(content), _xmlNSPrefix + "send")) { // --- SEND -------------------------- - send(content); + try { + send(content); + } + CATCH_AND_DISTRIBUTE("Error while sending content") } else if (boost::iequals(TAGNAME(content), _xmlNSPrefix + "cancel")) { // --- CANCEL -------------------------- std::string sendId; diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index f8cf823..d2c9025 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -251,6 +251,7 @@ protected: bool _stable; tthread::thread* _thread; tthread::recursive_mutex _mutex; + tthread::condition_variable _condVar; tthread::recursive_mutex _pluginMutex; URL _baseURI; @@ -291,13 +292,13 @@ protected: void executeContent(const Arabica::XPath::NodeSet<std::string>& content, bool rethrow = false); void processContentElement(const Arabica::DOM::Node<std::string>& element, - Arabica::DOM::Document<std::string>& dom, + Arabica::DOM::Node<std::string>& dom, std::string& text, 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, + void processDOMorText(const Arabica::DOM::Node<std::string>& element, + Arabica::DOM::Node<std::string>& dom, std::string& text); void send(const Arabica::DOM::Node<std::string>& element); diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp index ddb8996..f3f8c27 100644 --- a/src/uscxml/Message.cpp +++ b/src/uscxml/Message.cpp @@ -110,37 +110,37 @@ Arabica::DOM::Document<std::string> Data::toDocument() { return document; } -Arabica::DOM::Node<std::string> Event::getFirstDOMElement() const { - return getFirstDOMElement(dom); -} - -Arabica::DOM::Document<std::string> Event::getStrippedDOM() const { - return getStrippedDOM(dom); -} - -Arabica::DOM::Node<std::string> Event::getFirstDOMElement(const Arabica::DOM::Document<std::string> dom) { - Arabica::DOM::Node<std::string> data = dom.getDocumentElement().getFirstChild(); - while (data) { - if (data.getNodeType() == Arabica::DOM::Node_base::TEXT_NODE) { - std::string trimmed = boost::trim_copy(data.getNodeValue()); - if (trimmed.length() == 0) { - data = data.getNextSibling(); - continue; - } - } - break; - } - return data; -} - -Arabica::DOM::Document<std::string> Event::getStrippedDOM(const Arabica::DOM::Document<std::string> dom) { - Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); - Arabica::DOM::Document<std::string> document = domFactory.createDocument("", "", 0); - if (dom) { - document.getDocumentElement().appendChild(document.importNode(getFirstDOMElement(dom), true)); - } - return document; -} +//Arabica::DOM::Node<std::string> Event::getFirstDOMElement() const { +// return getFirstDOMElement(dom); +//} +// +//Arabica::DOM::Document<std::string> Event::getStrippedDOM() const { +// return getStrippedDOM(dom); +//} + +//Arabica::DOM::Node<std::string> Event::getFirstDOMElement(const Arabica::DOM::Document<std::string> dom) { +// Arabica::DOM::Node<std::string> data = dom.getDocumentElement().getFirstChild(); +// while (data) { +// if (data.getNodeType() == Arabica::DOM::Node_base::TEXT_NODE) { +// std::string trimmed = boost::trim_copy(data.getNodeValue()); +// if (trimmed.length() == 0) { +// data = data.getNextSibling(); +// continue; +// } +// } +// break; +// } +// return data; +//} +// +//Arabica::DOM::Document<std::string> Event::getStrippedDOM(const Arabica::DOM::Document<std::string> dom) { +// Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); +// Arabica::DOM::Document<std::string> document = domFactory.createDocument("", "", 0); +// if (dom) { +// document.getDocumentElement().appendChild(document.importNode(getFirstDOMElement(dom), true)); +// } +// return document; +//} Arabica::DOM::Document<std::string> Event::toDocument() { Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h index 1e7a7ca..afc536f 100644 --- a/src/uscxml/Message.h +++ b/src/uscxml/Message.h @@ -158,17 +158,18 @@ public: this->origintype = originType; } - Arabica::DOM::Document<std::string> getDOM() { + Arabica::DOM::Node<std::string> getDOM() { return dom; } - void setDOM(const Arabica::DOM::Document<std::string>& dom) { + void setDOM(const Arabica::DOM::Node<std::string>& dom) { this->dom = dom; } - Arabica::DOM::Node<std::string> getFirstDOMElement() const; - Arabica::DOM::Document<std::string> getStrippedDOM() const; - static Arabica::DOM::Node<std::string> getFirstDOMElement(const Arabica::DOM::Document<std::string> dom); - static Arabica::DOM::Document<std::string> getStrippedDOM(const Arabica::DOM::Document<std::string> dom); +// Arabica::DOM::Node<std::string> getFirstDOMElement() const; +// Arabica::DOM::Document<std::string> getStrippedDOM() const; +// +// static Arabica::DOM::Node<std::string> getFirstDOMElement(const Arabica::DOM::Document<std::string> dom); +// static Arabica::DOM::Document<std::string> getStrippedDOM(const Arabica::DOM::Document<std::string> dom); std::string getRaw() { return raw; @@ -239,7 +240,7 @@ protected: Type eventType; std::string origin; std::string origintype; - Arabica::DOM::Document<std::string> dom; + Arabica::DOM::Node<std::string> dom; std::string sendid; bool hideSendId; std::string invokeid; diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp index 4d60999..cefe935d 100644 --- a/src/uscxml/URL.cpp +++ b/src/uscxml/URL.cpp @@ -103,7 +103,7 @@ URLImpl::~URLImpl() { curl_easy_cleanup(_handle); } -URLImpl::operator Data() { +URLImpl::operator Data() const { Data data; data.compound["url"] = Data(asString(), Data::VERBATIM); data.compound["host"] = Data(_uri.host(), Data::VERBATIM); @@ -117,7 +117,7 @@ URLImpl::operator Data() { data.compound["statusMsg"] = Data(_statusMsg, Data::VERBATIM); - std::vector<std::string>::iterator pathIter = _pathComponents.begin(); + std::vector<std::string>::const_iterator pathIter = _pathComponents.begin(); while(pathIter != _pathComponents.end()) { data.compound["pathComponent"].array.push_back(Data(*pathIter, Data::VERBATIM)); pathIter++; diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h index 3acd462..16c29c7 100644 --- a/src/uscxml/URL.h +++ b/src/uscxml/URL.h @@ -95,7 +95,7 @@ public: bool downloadFailed() { return _hasFailed; } - operator Data(); + operator Data() const; friend class URLFetcher; @@ -249,7 +249,7 @@ public: friend class URLFetcher; friend std::ostream & operator<<(std::ostream &stream, const URL& p); - operator Data() { + operator Data() const { return _impl->operator Data(); } diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index 881fa8b..e044fcf 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -9,7 +9,6 @@ using namespace Arabica::DOM; // see: http://www.w3.org/TR/scxml/#AlgorithmforSCXMLInterpretation void InterpreterDraft6::interpret() { -// _mutex.lock(); tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); if (!_isInitialized) init(); @@ -264,7 +263,11 @@ void InterpreterDraft6::mainEventLoop() { while(_externalQueue.isEmpty() && _thread == NULL) { runOnMainThread(200); } + _mutex.lock(); + while(_externalQueue.isEmpty()) { + _condVar.wait(_mutex); + } _currEvent = _externalQueue.pop(); #if VERBOSE std::cout << "Received externalEvent event " << _currEvent.name << std::endl; @@ -273,8 +276,6 @@ void InterpreterDraft6::mainEventLoop() { if (!_running) goto EXIT_INTERPRETER; - _mutex.lock(); - if (_dataModel && boost::iequals(_currEvent.name, "cancel.invoke." + _sessionId)) break; diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 712799c..c714735 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -3,6 +3,9 @@ #include "JSCDataModel.h" #include "JSCDOM.h" #include "dom/JSCDocument.h" +#include "dom/JSCElement.h" +#include "dom/JSCText.h" +#include "dom/JSCCDATASection.h" #include "dom/JSCSCXMLEvent.h" #include "uscxml/Message.h" @@ -12,6 +15,13 @@ #include <Pluma/Connector.hpp> #endif +#define TO_JSC_DOMVALUE(type) \ +struct JSC##type::JSC##type##Private* privData = new JSC##type::JSC##type##Private(); \ +privData->dom = _dom; \ +privData->nativeObj = new type<std::string>(node); \ +JSObjectRef retObj = JSObjectMake(_ctx, JSC##type::getTmpl(), privData);\ +return retObj; + namespace uscxml { using namespace Arabica::XPath; @@ -96,24 +106,24 @@ boost::shared_ptr<DataModelImpl> JSCDataModel::create(InterpreterImpl* interpret JSClassRef jsInvokerClassRef = JSClassCreate(&jsInvokersClassDef); JSObjectRef jsInvoker = JSObjectMake(dm->_ctx, jsInvokerClassRef, dm.get()); JSStringRef invokerName = JSStringCreateWithUTF8CString("_invokers"); - JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), invokerName, jsInvoker, kJSPropertyAttributeNone, NULL); + JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), invokerName, jsInvoker, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, NULL); JSStringRelease(invokerName); JSClassRef jsIOProcClassRef = JSClassCreate(&jsIOProcessorsClassDef); JSObjectRef jsIOProc = JSObjectMake(dm->_ctx, jsIOProcClassRef, dm.get()); JSStringRef ioProcName = JSStringCreateWithUTF8CString("_ioprocessors"); - JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), ioProcName, jsIOProc, kJSPropertyAttributeNone, NULL); + JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), ioProcName, jsIOProc, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, NULL); JSStringRelease(ioProcName); JSStringRef nameName = JSStringCreateWithUTF8CString("_name"); JSStringRef name = JSStringCreateWithUTF8CString(dm->_interpreter->getName().c_str()); - JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), nameName, JSValueMakeString(dm->_ctx, name), kJSPropertyAttributeNone, NULL); + JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), nameName, JSValueMakeString(dm->_ctx, name), kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, NULL); JSStringRelease(nameName); JSStringRelease(name); JSStringRef sessionIdName = JSStringCreateWithUTF8CString("_sessionid"); JSStringRef sessionId = JSStringCreateWithUTF8CString(dm->_interpreter->getSessionId().c_str()); - JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), sessionIdName, JSValueMakeString(dm->_ctx, sessionId), kJSPropertyAttributeNone, NULL); + JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), sessionIdName, JSValueMakeString(dm->_ctx, sessionId), kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, NULL); JSStringRelease(sessionIdName); JSStringRelease(sessionId); @@ -153,7 +163,7 @@ void JSCDataModel::setEvent(const Event& event) { if (event.dom) { JSStringRef propName = JSStringCreateWithUTF8CString("data"); - JSObjectSetProperty(_ctx, eventObj, propName, getDocumentAsValue(event.dom), 0, &exception); + JSObjectSetProperty(_ctx, eventObj, propName, getNodeAsValue(event.dom), 0, &exception); JSStringRelease(propName); if (exception) handleException(exception); @@ -342,8 +352,19 @@ bool JSCDataModel::validate(const std::string& location, const std::string& sche } uint32_t JSCDataModel::getLength(const std::string& expr) { -// LOG(ERROR) << "I am not sure whether getLength() works :("; - JSValueRef result = evalAsValue("(" + expr + ").length"); + JSValueRef result; + + result = evalAsValue("(" + expr + ").length"); + JSType type = JSValueGetType(_ctx, result); + if (type == kJSTypeNull || type == kJSTypeUndefined) { + Event exceptionEvent; + exceptionEvent.data.compound["exception"] = Data("'" + expr + "' does not evaluate to an array.", Data::VERBATIM); + exceptionEvent.name = "error.execution"; + exceptionEvent.eventType = Event::PLATFORM; + + throw(exceptionEvent); + } + JSValueRef exception = NULL; double length = JSValueToNumber(_ctx, result, &exception); if (exception) @@ -424,7 +445,7 @@ JSValueRef JSCDataModel::evalAsValue(const std::string& expr, bool dontThrow) { } void JSCDataModel::assign(const Element<std::string>& assignElem, - const Document<std::string>& doc, + const Node<std::string>& node, const std::string& content) { std::string key; JSValueRef exception = NULL; @@ -436,10 +457,20 @@ void JSCDataModel::assign(const Element<std::string>& assignElem, if (key.length() == 0) throw Event("error.execution", Event::PLATFORM); + // flags on attribute are ignored? + if (key.compare("_sessionid") == 0) + throw Event("error.execution", Event::PLATFORM); + if (key.compare("_name") == 0) + throw Event("error.execution", Event::PLATFORM); + if (key.compare("_ioprocessors") == 0) + throw Event("error.execution", Event::PLATFORM); + if (key.compare("_invokers") == 0) + throw Event("error.execution", Event::PLATFORM); + if (HAS_ATTR(assignElem, "expr")) { evalAsValue(key + " = " + ATTR(assignElem, "expr")); - } else if (doc) { - JSObjectSetProperty(_ctx, JSContextGetGlobalObject(_ctx), JSStringCreateWithUTF8CString(key.c_str()), getDocumentAsValue(doc), 0, &exception); + } else if (node) { + JSObjectSetProperty(_ctx, JSContextGetGlobalObject(_ctx), JSStringCreateWithUTF8CString(key.c_str()), getNodeAsValue(node), 0, &exception); if (exception) handleException(exception); } else if (content.size() > 0) { @@ -455,15 +486,24 @@ void JSCDataModel::assign(const Element<std::string>& assignElem, } } -JSValueRef JSCDataModel::getDocumentAsValue(const Document<std::string>& doc) { - - struct JSCDocument::JSCDocumentPrivate* retPrivData = new JSCDocument::JSCDocumentPrivate(); - retPrivData->dom = _dom; - retPrivData->nativeObj = new Document<std::string>(doc); - - JSObjectRef retObj = JSObjectMake(_ctx, JSCDocument::getTmpl(), retPrivData); - - return retObj; +JSValueRef JSCDataModel::getNodeAsValue(const Node<std::string>& node) { + switch (node.getNodeType()) { + case Node_base::ELEMENT_NODE: { + TO_JSC_DOMVALUE(Element); + } + case Node_base::TEXT_NODE: { + TO_JSC_DOMVALUE(Text); + } + case Node_base::CDATA_SECTION_NODE: { + TO_JSC_DOMVALUE(CDATASection); + } + case Node_base::DOCUMENT_NODE: { + TO_JSC_DOMVALUE(Document); + } + default: { + TO_JSC_DOMVALUE(Node); + } + } } void JSCDataModel::assign(const std::string& location, const Data& data) { @@ -473,10 +513,10 @@ void JSCDataModel::assign(const std::string& location, const Data& data) { } void JSCDataModel::init(const Element<std::string>& dataElem, - const Document<std::string>& doc, + const Node<std::string>& node, const std::string& content) { try { - assign(dataElem, doc, content); + assign(dataElem, node, content); } catch (Event e) { // test 277 std::string key; diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h index f7360d4..9bb3034 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h @@ -50,12 +50,12 @@ public: virtual bool isDeclared(const std::string& expr); virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Document<std::string>& doc, + const Arabica::DOM::Node<std::string>& node, 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 Arabica::DOM::Node<std::string>& node, const std::string& content); virtual void init(const std::string& location, const Data& data); @@ -77,7 +77,7 @@ protected: static JSValueRef jsInvokerGetProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); static void jsInvokerListProps(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames); - JSValueRef getDocumentAsValue(const Arabica::DOM::Document<std::string>& doc); + JSValueRef getNodeAsValue(const Arabica::DOM::Node<std::string>& node); JSValueRef getDataAsValue(const Data& data); Data getValueAsData(const JSValueRef value); JSValueRef evalAsValue(const std::string& expr, bool dontThrow = false); diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEvent.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEvent.cpp index 579012b..de3a93f 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEvent.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEvent.cpp @@ -7,7 +7,7 @@ namespace DOM { JSClassRef JSCSCXMLEvent::Tmpl; JSStaticValue JSCSCXMLEvent::staticValues[] = { - { "eventType", eventTypeCustomAttrGetter, 0, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly }, + { "type", typeCustomAttrGetter, 0, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly }, { "name", nameAttrGetter, 0, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly }, { "origin", originAttrGetter, 0, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly }, { "origintype", origintypeAttrGetter, 0, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly }, diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEvent.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEvent.h index d3a25d5..5ac8ccb 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEvent.h +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEvent.h @@ -39,7 +39,7 @@ public: JSC_DESTRUCTOR(JSCSCXMLEventPrivate); - static JSValueRef eventTypeCustomAttrGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception); + static JSValueRef typeCustomAttrGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception); static JSValueRef nameAttrGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception); static JSValueRef originAttrGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception); static JSValueRef origintypeAttrGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception); diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEventCustom.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEventCustom.cpp index 0209467..e197796 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEventCustom.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCSCXMLEventCustom.cpp @@ -3,7 +3,7 @@ namespace Arabica { namespace DOM { -JSValueRef JSCSCXMLEvent::eventTypeCustomAttrGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception) { +JSValueRef JSCSCXMLEvent::typeCustomAttrGetter(JSContextRef ctx, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception) { struct JSCSCXMLEventPrivate* privData = (struct JSCSCXMLEventPrivate*)JSObjectGetPrivate(thisObj); JSStringRef stringRef; diff --git a/src/uscxml/plugins/datamodel/ecmascript/Storage.cpp b/src/uscxml/plugins/datamodel/ecmascript/Storage.cpp index 9131784..b5bb474 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/Storage.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/Storage.cpp @@ -5,7 +5,7 @@ namespace uscxml { Storage::Storage(const std::string& filename) { _filename = filename; - std::cout << _filename << std::endl; +// std::cout << _filename << std::endl; std::fstream file; file.open(_filename.c_str(), std::ios_base::in); // read content into data diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index 017b2eb..ea112f1 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -4,6 +4,9 @@ #include "V8DOM.h" #include "dom/V8Document.h" #include "dom/V8Node.h" +#include "dom/V8Element.h" +#include "dom/V8Text.h" +#include "dom/V8CDATASection.h" #include "dom/V8SCXMLEvent.h" #include "uscxml/Message.h" @@ -13,6 +16,17 @@ #include <Pluma/Connector.hpp> #endif +#define TO_V8_DOMVALUE(type) \ +v8::Handle<v8::Function> retCtor = V8##type::getTmpl()->GetFunction();\ +v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance());\ +struct V8##type::V8##type##Private* retPrivData = new V8##type::V8##type##Private();\ +retPrivData->dom = _dom;\ +retPrivData->nativeObj = new type<std::string>(node);\ +retObj->SetInternalField(0, V8DOM::toExternal(retPrivData));\ +retObj.MakeWeak(0, V8##type::jsDestructor);\ +return retObj; + + namespace uscxml { using namespace Arabica::XPath; @@ -152,7 +166,7 @@ void V8DataModel::setEvent(const Event& event) { eventObj.MakeWeak(0, V8SCXMLEvent::jsDestructor); if (event.dom) { - eventObj->Set(v8::String::New("data"), getDocumentAsValue(event.dom)); + eventObj->Set(v8::String::New("data"), getNodeAsValue(event.dom)); } else if (event.content.length() > 0) { // _event.data is a string or JSON Data json = Data::fromJSON(event.content); @@ -268,18 +282,26 @@ Data V8DataModel::getValueAsData(const v8::Handle<v8::Value>& value, std::set<v8 return data; } -v8::Handle<v8::Value> V8DataModel::getDocumentAsValue(const Document<std::string>& doc) { - v8::Handle<v8::Function> retCtor = V8Document::getTmpl()->GetFunction(); - v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance()); - - struct V8Document::V8DocumentPrivate* retPrivData = new V8Document::V8DocumentPrivate(); - retPrivData->dom = _dom; - retPrivData->nativeObj = new Document<std::string>(doc); +v8::Handle<v8::Value> V8DataModel::getNodeAsValue(const Node<std::string>& node) { - retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); - retObj.MakeWeak(0, V8Document::jsDestructor); + switch (node.getNodeType()) { + case Node_base::ELEMENT_NODE: { + TO_V8_DOMVALUE(Element); + } + case Node_base::TEXT_NODE: { + TO_V8_DOMVALUE(Text); + } + case Node_base::CDATA_SECTION_NODE: { + TO_V8_DOMVALUE(CDATASection); + } + case Node_base::DOCUMENT_NODE: { + TO_V8_DOMVALUE(Document); + } + default: { + TO_V8_DOMVALUE(Node); + } + } - return retObj; } v8::Handle<v8::Value> V8DataModel::getDataAsValue(const Data& data) { @@ -459,7 +481,7 @@ double V8DataModel::evalAsNumber(const std::string& expr) { } void V8DataModel::assign(const Element<std::string>& assignElem, - const Document<std::string>& doc, + const Node<std::string>& node, const std::string& content) { v8::Locker locker; v8::HandleScope handleScope; @@ -477,8 +499,8 @@ void V8DataModel::assign(const Element<std::string>& assignElem, 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 (node) { + global->Set(v8::String::New(key.c_str()), getNodeAsValue(node)); } else if (content.size() > 0) { try { evalAsValue(key + " = " + content); @@ -502,7 +524,7 @@ void V8DataModel::assign(const std::string& location, } void V8DataModel::init(const Element<std::string>& dataElem, - const Document<std::string>& doc, + const Node<std::string>& doc, const std::string& content) { try { assign(dataElem, doc, content); @@ -536,7 +558,6 @@ void V8DataModel::init(const std::string& location, evalAsValue(location + " = undefined", true); throw e; } - } diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h index 9d17093..0dffa27 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h @@ -50,13 +50,13 @@ public: virtual void eval(const Arabica::DOM::Element<std::string>& scriptElem, const std::string& expr); virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Document<std::string>& doc, + const Arabica::DOM::Node<std::string>& node, 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 Arabica::DOM::Node<std::string>& node, const std::string& content); virtual void init(const std::string& location, const Data& data); @@ -87,7 +87,7 @@ protected: 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); + v8::Handle<v8::Value> getNodeAsValue(const Arabica::DOM::Node<std::string>& node); void throwExceptionEvent(const v8::TryCatch& tryCatch); }; diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h index 3c5e6ee..9cc4ad4 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h @@ -41,7 +41,7 @@ public: static bool hasInstance(v8::Handle<v8::Value>); - static v8::Handle<v8::Value> eventTypeCustomAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); + static v8::Handle<v8::Value> typeCustomAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); static v8::Handle<v8::Value> nameAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); static v8::Handle<v8::Value> originAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); static v8::Handle<v8::Value> origintypeAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); @@ -63,7 +63,7 @@ public: instance->SetInternalFieldCount(1); - instance->SetAccessor(v8::String::NewSymbol("eventType"), V8SCXMLEvent::eventTypeCustomAttrGetter, 0, + instance->SetAccessor(v8::String::NewSymbol("type"), V8SCXMLEvent::typeCustomAttrGetter, 0, v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None)); instance->SetAccessor(v8::String::NewSymbol("name"), V8SCXMLEvent::nameAttrGetter, 0, v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None)); diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEventCustom.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEventCustom.cpp index d02a4cb..a8870cc 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEventCustom.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEventCustom.cpp @@ -3,7 +3,7 @@ namespace Arabica { namespace DOM { -v8::Handle<v8::Value> V8SCXMLEvent::eventTypeCustomAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) { +v8::Handle<v8::Value> V8SCXMLEvent::typeCustomAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) { v8::Local<v8::Object> self = info.Holder(); V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEventPrivate >(self->GetInternalField(0)); diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.h b/src/uscxml/plugins/datamodel/null/NULLDataModel.h index b86c01c..74d170f 100644 --- a/src/uscxml/plugins/datamodel/null/NULLDataModel.h +++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.h @@ -42,12 +42,12 @@ public: virtual void popContext(); virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Document<std::string>& doc, + const Arabica::DOM::Node<std::string>& node, 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 Arabica::DOM::Node<std::string>& node, const std::string& content) {} virtual void init(const std::string& location, const Data& data) {} diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp index a72fc6c..07cba96 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp @@ -223,7 +223,8 @@ void SWIDataModel::setEvent(const Event& event) { if (event.dom) { std::stringstream dataInitStr; std::stringstream xmlDoc; - xmlDoc << event.getFirstDOMElement(); +// xmlDoc << event.getFirstDOMElement(); + xmlDoc << event.dom; domUrl = URL::toLocalFile(xmlDoc.str(), ".pl"); dataInitStr << "load_xml_file('" << domUrl.asLocalFile(".pl") << "', XML), copy_term(XML,DATA), assert(event(data(DATA)))"; PlCall(dataInitStr.str().c_str()); @@ -408,7 +409,7 @@ std::map<std::string, PlTerm> SWIDataModel::resolveAtoms(PlTerm& term, PlTerm& o } void SWIDataModel::assign(const Element<std::string>& assignElem, - const Document<std::string>& doc, + const Node<std::string>& node, const std::string& content) { SET_PL_CONTEXT std::string expr = content; @@ -435,15 +436,15 @@ void SWIDataModel::assign(const Element<std::string>& assignElem, URL domUrl; Data json; - if (!doc) + if (!node) json = Data::fromJSON(expr); - if (doc) { + if (node) { std::stringstream dataInitStr; std::stringstream xmlDoc; - Node<std::string> node = Event::getFirstDOMElement(doc); + Node<std::string> child = node; while(node) { - xmlDoc << node; - node = node.getNextSibling(); + xmlDoc << child; + child = node.getNextSibling(); } domUrl = URL::toLocalFile(xmlDoc.str(), ".pl"); if (boost::iequals(type, "retract")) @@ -488,9 +489,9 @@ void SWIDataModel::assign(const std::string& location, const Data& data) { } void SWIDataModel::init(const Element<std::string>& dataElem, - const Document<std::string>& doc, + const Node<std::string>& node, const std::string& content) { - assign(dataElem, doc, content); + assign(dataElem, node, content); } void SWIDataModel::init(const std::string& location, const Data& data) { assign(location, data); diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h index 123e938..0a26643 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h @@ -42,12 +42,12 @@ public: virtual void popContext(); virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Document<std::string>& doc, + const Arabica::DOM::Node<std::string>& node, 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 Arabica::DOM::Node<std::string>& node, const std::string& content); virtual void init(const std::string& location, const Data& data); diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp index 842c560..cb40890 100644 --- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp +++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp @@ -174,7 +174,8 @@ void XPathDataModel::setEvent(const Event& event) { eventDataElem.appendChild(textNode); } if (event.dom) { - Node<std::string> importedNode = _doc.importNode(event.getFirstDOMElement(), true); +// Node<std::string> importedNode = _doc.importNode(event.getFirstDOMElement(), true); + Node<std::string> importedNode = _doc.importNode(event.dom, true); eventDataElem.appendChild(importedNode); } @@ -370,7 +371,7 @@ double XPathDataModel::evalAsNumber(const std::string& expr) { } void XPathDataModel::assign(const Element<std::string>& assignElem, - const Document<std::string>& doc, + const Node<std::string>& node, const std::string& content) { std::string location; if (HAS_ATTR(assignElem, "id")) { @@ -399,9 +400,9 @@ void XPathDataModel::assign(const Element<std::string>& assignElem, } #endif NodeSet<std::string> nodeSet; - if (doc) { - if (doc.getDocumentElement()) { - Node<std::string> data = doc.getDocumentElement().getFirstChild(); + if (node) { + if (node) { + Node<std::string> data = node; while (data) { // do not add empty text as a node if (data.getNodeType() == Node_base::TEXT_NODE) { @@ -447,7 +448,7 @@ NodeSet<std::string> XPathDataModel::dataToNodeSet(const Data& data) { } void XPathDataModel::init(const Element<std::string>& dataElem, - const Document<std::string>& doc, + const Node<std::string>& node, const std::string& content) { std::string location; if (HAS_ATTR(dataElem, "id")) { @@ -458,9 +459,9 @@ void XPathDataModel::init(const Element<std::string>& dataElem, Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", location); - if (doc) { - if (doc.getDocumentElement()) { - Node<std::string> data = doc.getDocumentElement().getFirstChild(); + if (node) { + if (node) { + Node<std::string> data = node; while (data) { Node<std::string> dataClone = _doc.importNode(data, true); container.appendChild(dataClone); @@ -504,10 +505,10 @@ void XPathDataModel::init(const Element<std::string>& dataElem, #if 0 nodeSet.push_back(container); #else - Node<std::string> node = container.getFirstChild(); - while(node) { - nodeSet.push_back(node); - node = node.getNextSibling(); + Node<std::string> child = container.getFirstChild(); + while(child) { + nodeSet.push_back(child); + child = child.getNextSibling(); } #endif _varResolver.setVariable(location, nodeSet); diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h index 240c62c..62ee439 100644 --- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h +++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h @@ -89,12 +89,12 @@ public: virtual void eval(const Arabica::DOM::Element<std::string>& scriptElem, const std::string& expr); virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Document<std::string>& doc, + const Arabica::DOM::Node<std::string>& node, 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 Arabica::DOM::Node<std::string>& node, const std::string& content); virtual void init(const std::string& location, const Data& data); diff --git a/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp b/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp index 6403a80..477a788 100644 --- a/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp +++ b/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp @@ -258,8 +258,8 @@ void OpenALInvoker::invoke(const InvokeRequest& req) { throw std::string("openal error create context"); } - std::cout << boost::lexical_cast<std::string>(_alContext); - std::cout << boost::lexical_cast<std::string>(_alDevice); +// std::cout << boost::lexical_cast<std::string>(_alContext); +// std::cout << boost::lexical_cast<std::string>(_alDevice); // alcMakeContextCurrent(_alContext); // float listener[3] = {0,0,0}; diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp index 06141c3..090f1b3 100644 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp @@ -49,11 +49,9 @@ void OSGInvoker::invoke(const InvokeRequest& req) { evTarget.addEventListener("DOMNodeRemoved", *this, false); evTarget.addEventListener("DOMAttrModified", *this, false); - Arabica::XPath::NodeSet<std::string> content = Interpreter::filterChildElements("content", req.dom); - std::set<std::string> validChilds; validChilds.insert("display"); - processChildren(validChilds, content[0]); + processChildren(validChilds, req.dom); } void OSGInvoker::runOnMainThread() { diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp index c697993..85c4b9c 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp @@ -35,7 +35,7 @@ Data USCXMLInvoker::getDataModelVariables() { } void USCXMLInvoker::send(const SendRequest& req) { - _invokedInterpreter.getImpl()->_externalQueue.push(req); + _invokedInterpreter.receive(req); } void USCXMLInvoker::cancel(const std::string sendId) { @@ -46,7 +46,12 @@ void USCXMLInvoker::invoke(const InvokeRequest& req) { if (req.src.length() > 0) { _invokedInterpreter = Interpreter::fromURI(req.src); } else if (req.dom) { - _invokedInterpreter = Interpreter::fromDOM(req.dom); + Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); + Arabica::DOM::Document<std::string> dom = domFactory.createDocument(req.dom.getNamespaceURI(), "", 0); + // we need to import the parent - to support xpath test150 + Arabica::DOM::Node<std::string> newNode = dom.importNode(req.dom, true); + dom.appendChild(newNode); + _invokedInterpreter = Interpreter::fromDOM(dom); } else if (req.content.size() > 0) { _invokedInterpreter = Interpreter::fromXML(req.content); } else { @@ -73,7 +78,8 @@ void USCXMLInvoker::invoke(const InvokeRequest& req) { /// test240 assumes that invoke request params will carry over to the datamodel _invokedInterpreter.getImpl()->setInvokeRequest(req); - _invokedInterpreter.getImpl()->start(); + _invokedInterpreter.start(); +// tthread::this_thread::sleep_for(tthread::chrono::seconds(1)); } else { /// test 530 _parentInterpreter->receive(Event("done.invoke." + _invokeId, Event::PLATFORM)); diff --git a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp index ddca2eb..c0d3329 100644 --- a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp @@ -58,7 +58,8 @@ void VoiceXMLInvoker::send(const SendRequest& req) { // } // } // } - domSS << req.getFirstDOMElement(); +// domSS << req.getFirstDOMElement(); + domSS << req.dom; start.content = domSS.str(); _interpreter->getDataModel().replaceExpressions(start.content); diff --git a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp index 059e7f5..acbf085 100644 --- a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp @@ -88,7 +88,8 @@ bool XHTMLInvoker::httpRecvRequest(const HTTPServer::Request& req) { std::string content; std::stringstream ss; if (_invokeReq.dom) { - ss << _invokeReq.getFirstDOMElement(); +// ss << _invokeReq.getFirstDOMElement(); + ss << _invokeReq.dom; content = ss.str(); } else if(_invokeReq.data) { ss << _invokeReq.data; @@ -160,14 +161,16 @@ void XHTMLInvoker::reply(const SendRequest& req, const HTTPServer::Request& long if (req.dom) { std::stringstream ss; - Arabica::DOM::Node<std::string> content = req.dom.getDocumentElement(); +// Arabica::DOM::Node<std::string> content = req.dom.getDocumentElement(); + Arabica::DOM::Node<std::string> content = req.dom; if (content && boost::iequals(content.getLocalName(), "content")) { reply.headers["X-SCXML-Type"] = (HAS_ATTR(content, "type") ? ATTR(content, "type") : "replacechildren"); reply.headers["X-SCXML-XPath"] = (HAS_ATTR(content, "xpath") ? ATTR(content, "xpath") : "/html/body"); if (HAS_ATTR(content, "attr")) reply.headers["X-SCXML-Attr"] = ATTR(content, "attr"); } - ss << req.getFirstDOMElement(); +// ss << req.getFirstDOMElement(); + ss << req.dom; reply.content = ss.str(); reply.headers["Content-Type"] = "application/xml"; } else if (req.data) { diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp index 56e2523..90cebc3 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp @@ -255,6 +255,16 @@ void BasicHTTPIOProcessor::downloadCompleted(const URL& url) { std::map<std::string, std::pair<URL, SendRequest> >::iterator reqIter = _sendRequests.begin(); while(reqIter != _sendRequests.end()) { if (reqIter->second.first == url) { + // test 513 + std::string statusCode = url.getStatusCode(); + if (statusCode.length() > 0) { + std::string statusPrefix = statusCode.substr(0,1); + std::string statusRest = statusCode.substr(1); + Event event; + event.data = url; + event.name = "HTTP." + statusPrefix + "." + statusRest; + returnEvent(event); + } _sendRequests.erase(reqIter); return; } diff --git a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp index 98d98e1..ac570c4 100644 --- a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp @@ -158,6 +158,7 @@ void SCXMLIOProcessor::send(const SendRequest& req) { LOG(ERROR) << "Not sure what to make of the target '" << reqCopy.target << "' - raising error" << std::endl; Event error("error.execution", Event::PLATFORM); error.sendid = reqCopy.sendid; + // test 159 still fails _interpreter->receiveInternal(error); } } |