diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-07-01 22:51:30 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-07-01 22:51:30 (GMT) |
commit | 945160d0539ad119ffc986fac712db76c7203e84 (patch) | |
tree | c43e4a7db898026bc62cc20af5061d07736f847e /src/uscxml | |
parent | c70d02010ea99e6c8e35da3b767f41f1ee5dce56 (diff) | |
download | uscxml-945160d0539ad119ffc986fac712db76c7203e84.zip uscxml-945160d0539ad119ffc986fac712db76c7203e84.tar.gz uscxml-945160d0539ad119ffc986fac712db76c7203e84.tar.bz2 |
More polishing for bindings C# and Java
Diffstat (limited to 'src/uscxml')
22 files changed, 230 insertions, 356 deletions
diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp index 3556aba..22482e6 100644 --- a/src/uscxml/Factory.cpp +++ b/src/uscxml/Factory.cpp @@ -516,7 +516,7 @@ boost::shared_ptr<InvokerImpl> Factory::createInvoker(const std::string& type, I if (_parentFactory) { return _parentFactory->createInvoker(type, interpreter); } else { - LOG(ERROR) << "No " << type << " Invoker known"; + ERROR_EXECUTION_THROW("No Invoker named '" + type + "' known"); } return boost::shared_ptr<InvokerImpl>(); @@ -538,7 +538,7 @@ boost::shared_ptr<DataModelImpl> Factory::createDataModel(const std::string& typ if (_parentFactory) { return _parentFactory->createDataModel(type, interpreter); } else { - LOG(ERROR) << "No " << type << " Datamodel known"; + ERROR_EXECUTION_THROW("No Datamodel name '" + type + "' known"); } return boost::shared_ptr<DataModelImpl>(); @@ -559,7 +559,7 @@ boost::shared_ptr<IOProcessorImpl> Factory::createIOProcessor(const std::string& if (_parentFactory) { return _parentFactory->createIOProcessor(type, interpreter); } else { - LOG(ERROR) << "No " << type << " IOProcessor known"; + ERROR_EXECUTION_THROW("No IOProcessor named '" + type + "' known"); } return boost::shared_ptr<IOProcessorImpl>(); @@ -578,7 +578,7 @@ boost::shared_ptr<ExecutableContentImpl> Factory::createExecutableContent(const if (_parentFactory) { return _parentFactory->createExecutableContent(localName, nameSpace, interpreter); } else { - LOG(ERROR) << "Executable content " << localName << " in " << actualNameSpace << " not available in factory"; + ERROR_EXECUTION_THROW("No Executable content name '" + localName + "' in namespace '" + actualNameSpace + "' known"); } return boost::shared_ptr<ExecutableContentImpl>(); @@ -654,51 +654,32 @@ Factory* Factory::getInstance() { } void EventHandlerImpl::returnErrorExecution(const std::string& cause) { - Event exceptionEvent; - exceptionEvent.data.compound["exception"] = Data(cause, Data::VERBATIM); - exceptionEvent.name = "error.execution"; - exceptionEvent.eventType = Event::PLATFORM; - returnEvent(exceptionEvent); + ERROR_EXECUTION(exc, cause); + returnEvent(exc); } -void EventHandlerImpl::returnErrorPlatform(const std::string& cause) { - Event exceptionEvent; - exceptionEvent.data.compound["exception"] = Data(cause, Data::VERBATIM); - exceptionEvent.name = "error.platform"; - exceptionEvent.eventType = Event::PLATFORM; - returnEvent(exceptionEvent); +void EventHandlerImpl::returnErrorCommunication(const std::string& cause) { + ERROR_COMMUNICATION(exc, cause); + returnEvent(exc); } -void EventHandlerImpl::returnEvent(Event& event) { +void EventHandlerImpl::returnEvent(Event& event, bool external) { if (event.invokeid.length() == 0) event.invokeid = _invokeId; if (event.eventType == 0) - event.eventType = Event::EXTERNAL; + event.eventType = (external ? Event::EXTERNAL : Event::INTERNAL); if (event.origin.length() == 0) event.origin = "#_" + _invokeId; if (event.origintype.length() == 0) event.origintype = _type; - - _interpreter->receive(event); -} - -void DataModelImpl::throwErrorExecution(const std::string& cause) { - uscxml::Event exc; - exc.data.compound["cause"] = uscxml::Data(cause, uscxml::Data::VERBATIM); - exc.name = "error.execution"; - exc.eventType = uscxml::Event::PLATFORM; - throw exc; -} - -void DataModelImpl::throwErrorPlatform(const std::string& cause) { - uscxml::Event exc; - exc.data.compound["cause"] = uscxml::Data(cause, uscxml::Data::VERBATIM); - exc.name = "error.platform"; - exc.eventType = uscxml::Event::PLATFORM; - throw exc; + + if (external) { + _interpreter->receive(event); + } else { + _interpreter->receiveInternal(event); + } } - Factory* Factory::_instance = NULL; std::string Factory::_defaultPluginPath; }
\ No newline at end of file diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 22fb79e..47a6182 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -83,6 +83,7 @@ #define VALID_FROM_MACROSTEPPED(newState) ( \ newState == USCXML_DESTROYED || \ newState == USCXML_MICROSTEPPED || \ + newState == USCXML_MACROSTEPPED || \ newState == USCXML_IDLE || \ newState == USCXML_FINISHED \ ) @@ -96,14 +97,7 @@ #define VALID_FROM_FINISHED(newState) ( \ newState == USCXML_DESTROYED || \ newState == USCXML_INSTANTIATED \ -) - -#define THROW_ERROR_PLATFORM(msg) \ - Event e; \ - e.name = "error.platform"; \ - e.data.compound["cause"] = Data(msg, Data::VERBATIM); \ - throw e; \ - +) /// macro to catch exceptions in executeContent #define CATCH_AND_DISTRIBUTE(msg) \ @@ -113,6 +107,7 @@ catch (Event e) {\ throw(e);\ } else {\ e.name = "error.execution";\ + e.data.compound["cause"] = uscxml::Data(msg, uscxml::Data::VERBATIM); \ e.eventType = Event::PLATFORM;\ receiveInternal(e);\ }\ @@ -120,11 +115,14 @@ catch (Event e) {\ #define CATCH_AND_DISTRIBUTE2(msg, node) \ catch (Event e) {\ - LOG(ERROR) << msg << " " << DOMUtils::xPathForNode(node) << ":" << std::endl << e << std::endl;\ + std::string xpathPos = DOMUtils::xPathForNode(node); \ + LOG(ERROR) << msg << " " << xpathPos << ":" << std::endl << e << std::endl;\ if (rethrow) {\ throw(e);\ } else {\ e.name = "error.execution";\ + e.data.compound["cause"] = uscxml::Data(msg, uscxml::Data::VERBATIM); \ + e.data.compound["xpath"] = uscxml::Data(xpathPos, uscxml::Data::VERBATIM); \ e.eventType = Event::PLATFORM;\ e.dom = node;\ receiveInternal(e);\ @@ -394,7 +392,7 @@ Interpreter Interpreter::fromURI(const std::string& uri) { URL absUrl(uri); if (!absUrl.isAbsolute()) { if (!absUrl.toAbsoluteCwd()) { - THROW_ERROR_PLATFORM("Given URL is not absolute or does not have file schema"); + ERROR_COMMUNICATION_THROW("URL is not absolute or does not have file schema"); } } @@ -416,7 +414,7 @@ Interpreter Interpreter::fromURI(const std::string& uri) { std::stringstream ss; ss << absUrl; if (absUrl.downloadFailed()) { - THROW_ERROR_PLATFORM("Downloading SCXML document from " + absUrl.asString() + " failed"); + ERROR_COMMUNICATION_THROW("Downloading SCXML document from '" + absUrl.asString() + "' failed"); } interpreter = fromXML(ss.str()); } @@ -426,7 +424,7 @@ Interpreter Interpreter::fromURI(const std::string& uri) { interpreter._impl->_baseURI = URL::asBaseURL(absUrl); interpreter._impl->_sourceURI = absUrl; } else { - THROW_ERROR_PLATFORM("Cannot create interpreter from URI " + absUrl.asString() + "'"); + ERROR_PLATFORM_THROW("Cannot create interpreter from URI '" + absUrl.asString() + "'"); } return interpreter; } @@ -454,9 +452,9 @@ Interpreter Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& interpreterImpl->_document = parser.getDocument(); } else { if (parser.errorsReported()) { - THROW_ERROR_PLATFORM(parser.errors()) + ERROR_PLATFORM_THROW(parser.errors()) } else { - THROW_ERROR_PLATFORM("Failed to create interpreter"); + ERROR_PLATFORM_THROW("Failed to create interpreter"); // interpreterImpl->setInterpreterState(USCXML_FAULTED, parser.errors()); } } @@ -680,11 +678,13 @@ void InterpreterImpl::reset() { _internalQueue.clear(); _historyValue.clear(); + _currEvent = Event(); _alreadyEntered = NodeSet<std::string>(); _configuration = NodeSet<std::string>(); _topLevelFinalReached = false; _isInitialized = false; - + _stable = false; + setInterpreterState(USCXML_INSTANTIATED); } @@ -693,9 +693,7 @@ void InterpreterImpl::setupAndNormalizeDOM() { return; if (!_document) { - Event error("error.platform"); - error.data.compound["cause"] = Data("Interpreter has no DOM", Data::VERBATIM); - throw error; + ERROR_PLATFORM_THROW("Interpreter has no DOM"); } // find scxml element @@ -707,9 +705,7 @@ void InterpreterImpl::setupAndNormalizeDOM() { } if (scxmls.getLength() == 0) { - Event error("error.platform"); - error.data.compound["cause"] = Data("Cannot find SCXML element in DOM", Data::VERBATIM); - throw error; + ERROR_PLATFORM_THROW("Cannot find SCXML element in DOM"); } _scxml = (Arabica::DOM::Element<std::string>)scxmls.item(0); @@ -777,12 +773,8 @@ void InterpreterImpl::init() { // instantiate datamodel if (HAS_ATTR(_scxml, "datamodel")) { + // might throw _dataModel = _factory->createDataModel(ATTR(_scxml, "datamodel"), this); - if (!_dataModel) { - Event e; - e.data.compound["cause"] = Data("Cannot instantiate datamodel", Data::VERBATIM); - throw e; - } } else { _dataModel = _factory->createDataModel("null", this); } @@ -1264,9 +1256,8 @@ void InterpreterImpl::delayedSend(void* userdata, std::string eventName) { * If the SCXML Processor does not support the type that is specified, it * must place the event error.execution on the internal event queue. */ - Event exceptionEvent("error.execution", Event::PLATFORM); -// exceptionEvent.sendid = sendReq.sendid; - INSTANCE->receiveInternal(exceptionEvent); + ERROR_EXECUTION(exc, "Unsupported type '" + sendReq.type + "' with send element"); + INSTANCE->receiveInternal(exc); } assert(INSTANCE->_sendIds.find(sendReq.sendid) != INSTANCE->_sendIds.end()); @@ -1372,7 +1363,12 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { if (invokeReq.type.size() == 0) invokeReq.type = "http://www.w3.org/TR/scxml/"; - Invoker invoker(_factory->createInvoker(invokeReq.type, this)); + Invoker invoker; + try { + invoker = _factory->createInvoker(invokeReq.type, this); + } catch (Event e) { + receiveInternal(e); + } if (invoker) { tthread::lock_guard<tthread::recursive_mutex> lock(_pluginMutex); try { @@ -1439,7 +1435,7 @@ void InterpreterImpl::cancelInvoke(const Arabica::DOM::Node<std::string>& elemen } USCXML_MONITOR_CALLBACK3(beforeUninvoking, Element<std::string>(element), invokeId) - + _invokers[invokeId].uninvoke(); _invokers.erase(invokeId); USCXML_MONITOR_CALLBACK3(beforeUninvoking, Element<std::string>(element), invokeId) @@ -1689,8 +1685,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont try { if (!_dataModel.isDeclared(ATTR(content, "location"))) { // test 286, 331 - LOG(ERROR) << "Assigning to undeclared location '" << ATTR(content, "location") << "' not allowed." << std::endl; - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Assigning to undeclared location '" + ATTR(content, "location") + "' not allowed."); } else { Node<std::string> dom; std::string text; @@ -1745,7 +1740,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont try { _dataModel.eval((Element<std::string>)content, srcContent.str()); } - CATCH_AND_DISTRIBUTE("Syntax error while executing script element from '" << ATTR(content, "src") << "':") + CATCH_AND_DISTRIBUTE("Syntax error while executing script element from '" + ATTR(content, "src") + "':") } else { if (content.hasChildNodes()) { // search for the text node with the actual script @@ -1791,16 +1786,9 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont // --- Custom Executable Content ExecutableContent execContent; if (_executableContent.find(content) == _executableContent.end()) { - execContent = _factory->createExecutableContent(content.getLocalName(), content.getNamespaceURI(), this); - if (!execContent) { - LOG(ERROR) << "No custom executable content known for element '" - << content.getLocalName() << "' in namespace '" << content.getNamespaceURI() << "'"; - return; - } - _executableContent[content] = execContent; - } else { - execContent = _executableContent[content]; + _executableContent[content] = _factory->createExecutableContent(content.getLocalName(), content.getNamespaceURI(), this); } + execContent = _executableContent[content]; execContent.enterElement(content); if (execContent.processChildren()) { @@ -2005,13 +1993,8 @@ Arabica::DOM::Node<std::string> InterpreterImpl::getState(const std::string& sta if (target.size() > 0) goto FOUND; - LOG(ERROR) << "No state with id " << stateId << " found!"; { - Event ev; - ev.name = "error.execution"; - ev.eventType = Event::PLATFORM; - ev.data.compound["cause"] = Data("No state with id " + stateId + " found", Data::VERBATIM); - throw ev; + ERROR_EXECUTION_THROW("No state with id '" + stateId + "' found"); } FOUND: if (target.size() > 0) { @@ -2403,6 +2386,7 @@ void InterpreterImpl::setupIOProcessors() { continue; } + // this might throw error.execution _ioProcessors[ioProcIter->first] = _factory->createIOProcessor(ioProcIter->first, this); _ioProcessors[ioProcIter->first].setType(ioProcIter->first); _ioProcessors[ioProcIter->first].setInterpreter(this); diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index a07d9af..cf281b5 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -46,6 +46,11 @@ #include "uscxml/plugins/Invoker.h" #include "uscxml/plugins/ExecutableContent.h" +#define ERROR_PLATFORM_THROW(msg) \ + Event e; \ + e.name = "error.platform"; \ + e.data.compound["cause"] = Data(msg, Data::VERBATIM); \ + throw e; \ #define USCXML_MONITOR_CATCH(callback) \ diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp index aaf4cde..08135fd 100644 --- a/src/uscxml/URL.cpp +++ b/src/uscxml/URL.cpp @@ -364,19 +364,19 @@ const void URLImpl::download(bool blocking) { _condVar.wait(_mutex); // wait for notification } if (_hasFailed) { - Event exception; - exception.name = "error.communication"; - exception.data = URL(shared_from_this()); + ERROR_COMMUNICATION(exc, _error); + exc.data = URL(shared_from_this()); if (_error.length() > 0) - exception.data.compound["reason"] = Data(_error, Data::VERBATIM); - throw exception; + exc.data.compound["cause"] = Data(_error, Data::VERBATIM); + throw exc; } if (iequals(scheme(), "http")) { if (_statusCode.size() > 0 && boost::lexical_cast<int>(_statusCode) > 400) { - Event exception; - exception.name = "error.communication"; - exception.data = URL(shared_from_this()); - throw exception; + ERROR_COMMUNICATION(exc, _error); + exc.data = URL(shared_from_this()); + if (_error.length() > 0) + exc.data.compound["cause"] = Data(_error, Data::VERBATIM); + throw exc; } } } diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index dd23a87..048adf9 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -135,21 +135,23 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { NodeSet<std::string> initialTransitions = getDocumentInitialTransitions(); assert(initialTransitions.size() > 0); enterStates(initialTransitions); + setInterpreterState(USCXML_MICROSTEPPED); } - _stable = false; - // are there spontaneous transitions? - enabledTransitions = selectEventlessTransitions(); - if (!enabledTransitions.empty()) { - // test 403b - enabledTransitions.to_document_order(); - microstep(enabledTransitions); + if (!_stable) { + enabledTransitions = selectEventlessTransitions(); + if (!enabledTransitions.empty()) { + // test 403b + enabledTransitions.to_document_order(); + microstep(enabledTransitions); - setInterpreterState(USCXML_MICROSTEPPED); - return _state; + setInterpreterState(USCXML_MICROSTEPPED); + return _state; + } + _stable = true; } - + // test415 if (_topLevelFinalReached) goto EXIT_INTERPRETER; @@ -158,6 +160,7 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { if (!_internalQueue.empty()) { _currEvent = _internalQueue.front(); _internalQueue.pop_front(); + _stable = false; USCXML_MONITOR_CALLBACK2(beforeProcessingEvent, _currEvent) @@ -178,14 +181,15 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { } else { _stable = true; } - // even if we did nothing - count as microstep - setInterpreterState(USCXML_MICROSTEPPED); + + if (_state != USCXML_MACROSTEPPED && _state != USCXML_IDLE) + USCXML_MONITOR_CALLBACK(onStableConfiguration) + + setInterpreterState(USCXML_MACROSTEPPED); if (_topLevelFinalReached) goto EXIT_INTERPRETER; - setInterpreterState(USCXML_MACROSTEPPED); - USCXML_MONITOR_CALLBACK(onStableConfiguration) // when we reach a stable configuration, invoke for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { @@ -227,7 +231,8 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { _currEvent = _externalQueue.pop(); _currEvent.eventType = Event::EXTERNAL; // make sure it is set to external - + _stable = false; + if (_topLevelFinalReached) goto EXIT_INTERPRETER; @@ -350,149 +355,6 @@ void InterpreterDraft6::stabilize() { } -#if 0 -void InterpreterDraft6::mainEventLoop() { - - while(_running) { - NodeSet<std::string> enabledTransitions; - _stable = false; - - // Here we handle eventless transitions and transitions - // triggered by internal events until machine is stable - while(_running && !_stable) { -#if VERBOSE - std::cout << "Configuration: "; - for (int i = 0; i < _configuration.size(); i++) { - std::cout << ATTR(_configuration[i], "id") << ", "; - } - std::cout << std::endl; -#endif - - enabledTransitions = selectEventlessTransitions(); - if (enabledTransitions.size() == 0) { - if (_internalQueue.size() == 0) { - _stable = true; - } else { - _currEvent = _internalQueue.front(); - _internalQueue.pop_front(); -#if VERBOSE - std::cout << "Received internal event " << _currEvent.name << std::endl; -#endif - - USCXML_MONITOR_CALLBACK(beforeProcessingEvent) - - if (_dataModel) - _dataModel.setEvent(_currEvent); - enabledTransitions = selectTransitions(_currEvent.name); - } - } - if (!enabledTransitions.empty()) { - // test 403b - enabledTransitions.to_document_order(); - microstep(enabledTransitions); - } - } - - for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { - NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); - for (unsigned int j = 0; j < invokes.size(); j++) { - if (!HAS_ATTR(invokes[j], "persist") || !DOMUtils::attributeIsTrue(ATTR(invokes[j], "persist"))) { - invoke(invokes[j]); - } - } - } - _statesToInvoke = NodeSet<std::string>(); - - if (!_internalQueue.empty()) - continue; - - // assume that we have a legal configuration as soon as the internal queue is empty - assert(hasLegalConfiguration()); - - USCXML_MONITOR_CALLBACK(onStableConfiguration) - - _mutex.unlock(); - - // whenever we have a stable configuration, run the mainThread hooks with 200fps - 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; - if (_running && _currEvent.name == "unblock.and.die") { - std::cout << "Still running " << this << std::endl; - } else { - std::cout << "Aborting " << this << std::endl; - } -#endif - _currEvent.eventType = Event::EXTERNAL; // make sure it is set to external - if (!_running) - goto EXIT_INTERPRETER; - - USCXML_MONITOR_CALLBACK(beforeProcessingEvent) - - if (_dataModel && iequals(_currEvent.name, "cancel.invoke." + _sessionId)) - break; - - if (_dataModel) { - try { - _dataModel.setEvent(_currEvent); - } catch (Event e) { - LOG(ERROR) << "Syntax error while setting external event:" << std::endl << e << std::endl << _currEvent; - } - } - for (std::map<std::string, Invoker>::iterator invokeIter = _invokers.begin(); - invokeIter != _invokers.end(); - invokeIter++) { - if (iequals(invokeIter->first, _currEvent.invokeid)) { - Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_nsInfo.xmlNSPrefix + "finalize", invokeIter->second.getElement()); - for (int k = 0; k < finalizes.size(); k++) { - Element<std::string> finalizeElem = Element<std::string>(finalizes[k]); - executeContent(finalizeElem); - } - } - if (HAS_ATTR(invokeIter->second.getElement(), "autoforward") && DOMUtils::attributeIsTrue(ATTR(invokeIter->second.getElement(), "autoforward"))) { - try { - // do not autoforward to invokers that send to #_parent from the SCXML IO Processor! - // Yes do so, see test229! - // if (!boost::equals(_currEvent.getOriginType(), "http://www.w3.org/TR/scxml/#SCXMLEventProcessor")) - invokeIter->second.send(_currEvent); - } catch(...) { - LOG(ERROR) << "Exception caught while sending event to invoker " << invokeIter->first; - } - } - } - enabledTransitions = selectTransitions(_currEvent.name); - if (!enabledTransitions.empty()) { - // test 403b - enabledTransitions.to_document_order(); - microstep(enabledTransitions); - } - } - -EXIT_INTERPRETER: - USCXML_MONITOR_CALLBACK(beforeCompletion) - - exitInterpreter(); - if (_sendQueue) { - std::map<std::string, std::pair<InterpreterImpl*, SendRequest> >::iterator sendIter = _sendIds.begin(); - while(sendIter != _sendIds.end()) { - _sendQueue->cancelEvent(sendIter->first); - sendIter++; - } - } - - USCXML_MONITOR_CALLBACK(afterCompletion) - -} -#endif - Arabica::XPath::NodeSet<std::string> InterpreterDraft6::selectTransitions(const std::string& event) { Arabica::XPath::NodeSet<std::string> enabledTransitions; diff --git a/src/uscxml/messages/Data.h b/src/uscxml/messages/Data.h index bf13409..9b5bea7 100644 --- a/src/uscxml/messages/Data.h +++ b/src/uscxml/messages/Data.h @@ -141,6 +141,14 @@ public: return data; } + void put(std::string key, const Data& data) { + compound[key] = data; + } + + void put(size_t index, const Data& data) { + this[index] = data; + } + bool operator==(const Data &other) const { if (other.atom.size() != atom.size()) return false; diff --git a/src/uscxml/messages/Event.cpp b/src/uscxml/messages/Event.cpp index a3e6a20..f8a880f 100644 --- a/src/uscxml/messages/Event.cpp +++ b/src/uscxml/messages/Event.cpp @@ -155,6 +155,8 @@ std::ostream& operator<< (std::ostream& os, const Event& event) { os << indent << " origin: " << event.origin << std::endl; if (event.origintype.size() > 0) os << indent << " origintype: " << event.origintype << std::endl; + if (event.content.size() > 0) + os << indent << " content: '" << event.content << "'" << std::endl; if (event.params.size() > 0) { std::multimap<std::string, Data>::const_iterator paramIter = event.params.begin(); os << indent << " params:" << std::endl; diff --git a/src/uscxml/messages/Event.h b/src/uscxml/messages/Event.h index 1acfce7..6697bb9 100644 --- a/src/uscxml/messages/Event.h +++ b/src/uscxml/messages/Event.h @@ -22,6 +22,56 @@ #include "uscxml/messages/Data.h" +#define ERROR_EXECUTION(identifier, cause) \ + uscxml::Event identifier; \ + identifier.data.compound["cause"] = uscxml::Data(cause, uscxml::Data::VERBATIM); \ + identifier.name = "error.execution"; \ + identifier.eventType = uscxml::Event::PLATFORM; + +#define ERROR_EXECUTION2(identifier, cause, node) \ + uscxml::Event identifier; \ + identifier.data.compound["cause"] = uscxml::Data(cause, uscxml::Data::VERBATIM); \ + identifier.name = "error.execution"; \ + identifier.data.compound["xpath"] = uscxml::Data(DOMUtils::xPathForNode(node), uscxml::Data::VERBATIM); \ + identifier.eventType = uscxml::Event::PLATFORM; + +#define ERROR_COMMUNICATION(identifier, cause) \ + uscxml::Event identifier; \ + identifier.data.compound["cause"] = uscxml::Data(cause, uscxml::Data::VERBATIM); \ + identifier.name = "error.communication"; \ + identifier.eventType = uscxml::Event::PLATFORM; + +#define ERROR_COMMUNICATION2(identifier, cause, node) \ + uscxml::Event identifier; \ + identifier.data.compound["cause"] = uscxml::Data(cause, uscxml::Data::VERBATIM); \ + identifier.name = "error.communication"; \ + identifier.data.compound["xpath"] = uscxml::Data(DOMUtils::xPathForNode(node), uscxml::Data::VERBATIM); \ + identifier.eventType = uscxml::Event::PLATFORM; + +#define ERROR_EXECUTION_THROW(cause) \ +{\ + ERROR_EXECUTION(exc, cause); \ + throw exc;\ +} + +#define ERROR_EXECUTION_THROW2(cause, node) \ +{\ + ERROR_EXECUTION2(exc, cause, node); \ + throw exc;\ +} + +#define ERROR_COMMUNICATION_THROW(cause) \ +{\ + ERROR_COMMUNICATION(exc, cause); \ + throw exc;\ +} + +#define ERROR_COMMUNICATION_THROW2(cause, node) \ +{\ + ERROR_COMMUNICATION(exc, cause, node); \ + throw exc;\ +} + namespace uscxml { class USCXML_API Event { @@ -145,6 +195,13 @@ public: return params; } + void setNameList(const std::map<std::string, Data>& nameList) { + this->namelist = nameList; + } + void setParams(const std::multimap<std::string, Data>& params) { + this->params = params; + } + typedef std::multimap<std::string, Data> params_t; typedef std::map<std::string, Data> namelist_t; diff --git a/src/uscxml/messages/InvokeRequest.cpp b/src/uscxml/messages/InvokeRequest.cpp index a39c8c6..26d40ce 100644 --- a/src/uscxml/messages/InvokeRequest.cpp +++ b/src/uscxml/messages/InvokeRequest.cpp @@ -60,6 +60,7 @@ std::ostream& operator<< (std::ostream& os, const InvokeRequest& invokeReq) { if (invokeReq.src.size() > 0) os<< indent << " src: " << invokeReq.src << std::endl; +#if 0 if (invokeReq.namelist.size() > 0) { os << indent << " namelist: " << std::endl; InvokeRequest::namelist_t::const_iterator namelistIter = invokeReq.namelist.begin(); @@ -80,6 +81,7 @@ std::ostream& operator<< (std::ostream& os, const InvokeRequest& invokeReq) { if (invokeReq.content.size() > 0) os << indent << " content: " << invokeReq.content << std::endl; +#endif _dataIndentation++; os << (Event)invokeReq; diff --git a/src/uscxml/messages/SendRequest.cpp b/src/uscxml/messages/SendRequest.cpp index a8fbe13..497182c 100644 --- a/src/uscxml/messages/SendRequest.cpp +++ b/src/uscxml/messages/SendRequest.cpp @@ -103,7 +103,7 @@ std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq) { if (sendReq.delayMs > 0) os<< indent << " delay: " << sendReq.delayMs << std::endl; - +#if 0 if (sendReq.namelist.size() > 0) { os << indent << " namelist: " << std::endl; SendRequest::namelist_t::const_iterator namelistIter = sendReq.namelist.begin(); @@ -124,7 +124,7 @@ std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq) { if (sendReq.content.size() > 0) os << indent << " content: " << sendReq.content << std::endl; - +#endif _dataIndentation++; os << (Event)sendReq; _dataIndentation--; diff --git a/src/uscxml/plugins/DataModel.h b/src/uscxml/plugins/DataModel.h index 57d4b14..f142a60 100644 --- a/src/uscxml/plugins/DataModel.h +++ b/src/uscxml/plugins/DataModel.h @@ -86,10 +86,6 @@ public: return ""; } - static void throwErrorExecution(const std::string& cause); - static void throwErrorPlatform(const std::string& cause); - - // we need it public for various static functions protected: InterpreterImpl* _interpreter; }; diff --git a/src/uscxml/plugins/EventHandler.h b/src/uscxml/plugins/EventHandler.h index d30feb9..7b38575 100644 --- a/src/uscxml/plugins/EventHandler.h +++ b/src/uscxml/plugins/EventHandler.h @@ -62,9 +62,9 @@ public: virtual void send(const SendRequest& req) = 0; virtual void runOnMainThread() {}; - void returnEvent(Event& event); + void returnEvent(Event& event, bool external = false); void returnErrorExecution(const std::string&); - void returnErrorPlatform(const std::string&); + void returnErrorCommunication(const std::string&); protected: InterpreterImpl* _interpreter; diff --git a/src/uscxml/plugins/Invoker.h b/src/uscxml/plugins/Invoker.h index c967331..4a142e4 100644 --- a/src/uscxml/plugins/Invoker.h +++ b/src/uscxml/plugins/Invoker.h @@ -33,6 +33,7 @@ class USCXML_API InvokerImpl : public EventHandlerImpl { public: virtual ~InvokerImpl() {} virtual void invoke(const InvokeRequest& req) = 0; + virtual void uninvoke() {} virtual boost::shared_ptr<InvokerImpl> create(InterpreterImpl* interpreter) = 0; }; @@ -65,6 +66,10 @@ public: _impl->invoke(req); } + virtual void uninvoke() { + _impl->uninvoke(); + } + protected: boost::shared_ptr<InvokerImpl> _impl; }; diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index b2fce62..6dc8c26 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -452,12 +452,7 @@ uint32_t JSCDataModel::getLength(const std::string& expr) { 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); + ERROR_EXECUTION_THROW("'" + expr + "' does not evaluate to an array."); } JSValueRef exception = NULL; @@ -549,20 +544,20 @@ void JSCDataModel::assign(const Element<std::string>& assignElem, } else if (HAS_ATTR(assignElem, "location")) { key = ATTR(assignElem, "location"); } - if (key.length() == 0) - throw Event("error.execution", Event::PLATFORM); - + if (key.length() == 0) { + ERROR_EXECUTION_THROW("Assign element has neither id nor location"); + } // flags on attribute are ignored? if (key.compare("_sessionid") == 0) // test 322 - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Cannot assign to _sessionId"); if (key.compare("_name") == 0) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Cannot assign to _name"); if (key.compare("_ioprocessors") == 0) // test 326 - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Cannot assign to _ioprocessors"); if (key.compare("_invokers") == 0) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Cannot assign to _invokers"); if (key.compare("_event") == 0) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Cannot assign to _event"); if (HAS_ATTR(assignElem, "expr")) { evalAsValue(key + " = " + ATTR(assignElem, "expr")); @@ -666,13 +661,7 @@ void JSCDataModel::handleException(JSValueRef exception) { JSStringRelease(exceptionStringRef); std::string exceptionMsg(buffer); - Event exceptionEvent; - exceptionEvent.data.compound["exception"] = Data(exceptionMsg, Data::VERBATIM); - exceptionEvent.name = "error.execution"; - exceptionEvent.eventType = Event::PLATFORM; - - throw(exceptionEvent); - + ERROR_EXECUTION_THROW(exceptionMsg); } JSValueRef JSCDataModel::jsPrint(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp index 98d2dda..45d7a5c 100644 --- a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp +++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp @@ -65,7 +65,10 @@ void NULLDataModel::setEvent(const Event& event) { } Data NULLDataModel::getStringAsData(const std::string& content) { - Data data; + Data data = Data::fromJSON(content); + if (data.empty()) { + data = Data(content, Data::VERBATIM); + } return data; } diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp index ad0c42b..8f5e588 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp @@ -37,10 +37,7 @@ extern "C" { } #define RETHROW_PLEX_AS_EVENT \ catch (PlException plex) { \ - Event e; \ - e.name = "error.execution"; \ - e.data.compound["cause"] = (char*)plex; \ - throw e; \ + ERROR_EXECUTION_THROW((char*)plex); \ } \ #define PL_MODULE \ @@ -733,10 +730,7 @@ std::string SWIDataModel::evalAsString(const std::string& expr) { if (term.type() == PL_ATOM || term.type() == PL_CHARS || term.type() == PL_STRING) { return std::string(term); } else { - Event e; - e.name = "error.execution"; - e.data.compound["cause"] = (char*)plex; - throw e; + ERROR_EXECUTION_THROW((char*)plex); } } } diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp index 8bfc39d..4300512 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp @@ -100,11 +100,11 @@ bool PromelaDataModel::validate(const std::string& location, const std::string& uint32_t PromelaDataModel::getLength(const std::string& expr) { if (!isDeclared(expr)) { - throwErrorExecution("Variable " + expr + " was not declared"); + ERROR_EXECUTION_THROW("Variable '" + expr + "' was not declared"); } if (!_variables[expr].hasKey("size")) { - throwErrorExecution("Variable " + expr + " is no array"); + ERROR_EXECUTION_THROW("Variable '" + expr + "' is no array"); } return strTo<int>(_variables[expr]["size"].atom); @@ -216,7 +216,7 @@ void PromelaDataModel::evaluateDecl(void* ast) { _variables.compound[name->value] = variable; } else { - throwErrorExecution("Declaring variables via " + PromelaParserNode::typeToDesc((*nameIter)->type) + " not implemented"); + ERROR_EXECUTION_THROW("Declaring variables via " + PromelaParserNode::typeToDesc((*nameIter)->type) + " not implemented"); } } assert(opIter == node->operands.end()); @@ -227,7 +227,7 @@ void PromelaDataModel::evaluateDecl(void* ast) { evaluateDecl(*declIter); } } else { - throwErrorExecution("Declaring variables via " + PromelaParserNode::typeToDesc(node->type) + " not implemented"); + ERROR_EXECUTION_THROW("Declaring variables via " + PromelaParserNode::typeToDesc(node->type) + " not implemented"); } } @@ -269,7 +269,7 @@ int PromelaDataModel::evaluateExpr(void* ast) { case PML_OR: return evaluateExpr(*opIter++) != 0 || evaluateExpr(*opIter++) != 0; default: - throwErrorExecution("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); + ERROR_EXECUTION_THROW("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); } return 0; } @@ -291,7 +291,7 @@ void PromelaDataModel::evaluateStmnt(void* ast) { break; } default: - throwErrorExecution("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); + ERROR_EXECUTION_THROW("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); } } @@ -306,15 +306,15 @@ void PromelaDataModel::setVariable(void* ast, int value) { int index = evaluateExpr(expr); if (_variables.compound.find(name->value) == _variables.compound.end()) { - throwErrorExecution("No variable " + name->value + " was declared"); + ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } if (!_variables[name->value].hasKey("size")) { - throwErrorExecution("Variable " + name->value + " is no array"); + ERROR_EXECUTION_THROW("Variable " + name->value + " is no array"); } if (strTo<int>(_variables[name->value]["size"].atom) <= index) { - throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); + ERROR_EXECUTION_THROW("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); } _variables.compound[name->value].compound["value"][index] = Data(value, Data::VERBATIM); @@ -339,10 +339,10 @@ int PromelaDataModel::getVariable(void* ast) { switch(node->type) { case PML_NAME: if (_variables.compound.find(node->value) == _variables.compound.end()) { - throwErrorExecution("No variable " + node->value + " was declared"); + ERROR_EXECUTION_THROW("No variable " + node->value + " was declared"); } if (_variables[node->value].compound.find("size") != _variables[node->value].compound.end()) { - throwErrorExecution("Type error: Variable " + node->value + " is an array"); + ERROR_EXECUTION_THROW("Type error: Variable " + node->value + " is an array"); } return strTo<int>(_variables[node->value]["value"].atom); case PML_VAR_ARRAY: { @@ -351,20 +351,20 @@ int PromelaDataModel::getVariable(void* ast) { int index = evaluateExpr(expr); if (_variables.compound.find(name->value) == _variables.compound.end()) { - throwErrorExecution("No variable " + name->value + " was declared"); + ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } if (!_variables[name->value].hasKey("size")) { - throwErrorExecution("Variable " + name->value + " is no array"); + ERROR_EXECUTION_THROW("Variable " + name->value + " is no array"); } if (strTo<int>(_variables[name->value]["size"].atom) <= index) { - throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); + ERROR_EXECUTION_THROW("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); } return strTo<int>(_variables.compound[name->value].compound["value"][index].atom); } default: - throwErrorExecution("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); + ERROR_EXECUTION_THROW("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); } return 0; } diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp index cd3bbaf..d12b7fc 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp @@ -19,6 +19,7 @@ #include "PromelaParser.h" #include "parser/promela.tab.hpp" +#include "uscxml/messages/Event.h" #include <iostream> @@ -35,10 +36,7 @@ int promela_lex_destroy (void*); void promela_error (uscxml::PromelaParser* ctx, void* yyscanner, const char* err) { // mark as pending exception as we cannot throw from constructor and have the destructor called - uscxml::Event excEvent; - excEvent.data.compound["exception"] = uscxml::Data(err, uscxml::Data::VERBATIM); - excEvent.name = "error.execution"; - excEvent.eventType = uscxml::Event::PLATFORM; + ERROR_EXECUTION(excEvent, err); ctx->pendingException = excEvent; } @@ -53,12 +51,7 @@ PromelaParser::PromelaParser(const std::string& expr, Type expectedType) { if (type != expectedType) { std::stringstream ss; ss << "Promela syntax type mismatch: Expected " << typeToDesc(expectedType) << " but got " << typeToDesc(type); - - uscxml::Event excEvent; - excEvent.data.compound["exception"] = uscxml::Data(ss.str(), uscxml::Data::VERBATIM); - excEvent.name = "error.execution"; - excEvent.eventType = uscxml::Event::PLATFORM; - throw excEvent; + ERROR_EXECUTION_THROW(ss.str()); } } diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp index 4d9854b..5800f98 100644 --- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp +++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp @@ -296,9 +296,7 @@ uint32_t XPathDataModel::getLength(const std::string& expr) { return result.asNodeSet().size(); break; default: - Event exceptionEvent("error.execution", Event::PLATFORM); - exceptionEvent.data.compound["exception"] = Data("'" + expr + "' does not evaluate to an array.", Data::VERBATIM); - throw(exceptionEvent); + ERROR_EXECUTION_THROW("'" + expr + "' does not evaluate to an array."); } return 0; } @@ -326,7 +324,7 @@ void XPathDataModel::setForeach(const std::string& item, if (!isDeclared(item)) { if (!isValidIdentifier(item)) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Expression '" + item + "' not a valid identifier."); Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", item); container.appendChild(arrayResult.asNodeSet()[iteration].cloneNode(true)); @@ -400,9 +398,9 @@ bool XPathDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, con try { result = _xpath.evaluate_expr(expr, _doc); } catch(SyntaxException e) { - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW(e.what()); } catch(std::runtime_error e) { - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW(e.what()); } return result.asBool(); } @@ -413,9 +411,9 @@ std::string XPathDataModel::evalAsString(const std::string& expr) { try { result = _xpath.evaluate_expr(expr, _doc); } catch(SyntaxException e) { - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW(e.what()); } catch(std::runtime_error e) { - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW(e.what()); } switch (result.type()) { case STRING: @@ -440,7 +438,7 @@ std::string XPathDataModel::evalAsString(const std::string& expr) { break; } case ANY: - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Type ANY not supported to evaluate as string"); break; } return "undefined"; @@ -472,13 +470,13 @@ void XPathDataModel::assign(const Element<std::string>& assignElem, for (int i = 0; i < key.asNodeSet().size(); i++) { Node<std::string> node = key.asNodeSet()[i]; if (node == _varResolver.resolveVariable("", "_ioprocessors").asNodeSet()[0]) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Cannot assign _ioProcessors"); if (node == _varResolver.resolveVariable("", "_sessionid").asNodeSet()[0]) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Cannot assign _sessionid"); if (node == _varResolver.resolveVariable("", "_name").asNodeSet()[0]) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Cannot assign _name"); if (node == _varResolver.resolveVariable("", "_event").asNodeSet()[0]) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Cannot assign _event"); } } catch (Event e) {} } @@ -570,11 +568,11 @@ void XPathDataModel::init(const Element<std::string>& dataElem, } case Arabica::XPath::BOOL: case ANY: - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("expr evaluates to type ANY"); } _datamodel.appendChild(container); } catch (SyntaxException e) { - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW(e.what()); } } else { LOG(ERROR) << "data element has no content"; @@ -595,7 +593,7 @@ void XPathDataModel::assign(const XPathValue<std::string>& key, switch (key.type()) { case NODE_SET: if (key.asNodeSet().size() == 0) { - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("key for assign is empty nodeset"); } switch (value.type()) { case STRING: @@ -611,14 +609,14 @@ void XPathDataModel::assign(const XPathValue<std::string>& key, assign(key.asNodeSet(), value.asNodeSet(), assignElem); break; case ANY: - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Type ANY as key for assign not supported"); } break; case STRING: case Arabica::XPath::BOOL: case NUMBER: case ANY: - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Type ANY as key for assign not supported") break; } } @@ -637,7 +635,7 @@ void XPathDataModel::assign(const XPathValue<std::string>& key, case Arabica::XPath::BOOL: case NUMBER: case ANY: - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Type ANY as key for assign not supported") } } @@ -665,7 +663,7 @@ void XPathDataModel::assign(const NodeSet<std::string>& key, // 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); + ERROR_EXECUTION_THROW("Assign element is missing 'attr'") element.setAttribute(ATTR(assignElem, "attr"), value); } else { /// test 547 @@ -677,7 +675,7 @@ void XPathDataModel::assign(const NodeSet<std::string>& key, break; } default: - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Unsupported node type with assign"); break; } } @@ -709,7 +707,7 @@ void XPathDataModel::assign(const NodeSet<std::string>& key, break; default: // std::cout << key[i].getNodeType() << std::endl; - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Unsupported node type for assign"); break; } } @@ -740,7 +738,7 @@ void XPathDataModel::assign(const Element<std::string>& key, // node specified by 'location', keeping the same parent. Node<std::string> parent = element.getParentNode(); if (!parent) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Node has no parent"); for (int i = 0; i < value.size(); i++) { Node<std::string> importedNode = (value[i].getOwnerDocument() == _doc ? value[i].cloneNode(true) : _doc.importNode(value[i], true)); parent.insertBefore(importedNode, element); @@ -750,7 +748,7 @@ void XPathDataModel::assign(const Element<std::string>& key, // specified by 'location', keeping the same parent. Node<std::string> parent = element.getParentNode(); if (!parent) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Node has no parent"); for (int i = value.size(); i; i--) { Node<std::string> importedNode = (value[i-1].getOwnerDocument() == _doc ? value[i-1].cloneNode(true) : _doc.importNode(value[i-1], true)); Node<std::string> nextSibling = element.getNextSibling(); @@ -764,16 +762,16 @@ void XPathDataModel::assign(const Element<std::string>& key, // 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); + ERROR_EXECUTION_THROW("Node has no parent"); if (value.size() != 1) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Value not singular"); Node<std::string> importedNode = (value[0].getOwnerDocument() == _doc ? value[0].cloneNode(true) : _doc.importNode(value[0], true)); parent.replaceChild(importedNode, element); } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "delete")) { // delete: Delete the node specified by 'location'. ('expr' is ignored.). Node<std::string> parent = element.getParentNode(); if (!parent) - throw Event("error.execution", Event::PLATFORM); + ERROR_EXECUTION_THROW("Node has no parent"); parent.removeChild(element); } else { // replacechildren: Replace all the children at 'location' with the value specified by 'expr'. @@ -791,7 +789,7 @@ 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"); + ERROR_EXECUTION_THROW("No varable named '" + name + "'"); } #if VERBOSE std::cout << std::endl << "Getting " << name << ":" << std::endl; diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp index 5ee7357..bd62467 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp @@ -157,7 +157,7 @@ bool BasicHTTPIOProcessor::httpRecvRequest(const HTTPServer::Request& req) { if (reqEvent.name.length() == 0) reqEvent.name = "http." + req.data.compound.at("type").atom; - returnEvent(reqEvent); + returnEvent(reqEvent, true); evhttp_send_reply(req.evhttpReq, 200, "OK", NULL); return true; } @@ -287,7 +287,7 @@ void BasicHTTPIOProcessor::downloadCompleted(const URL& url) { Event event; event.data = url; event.name = "HTTP." + statusPrefix + "." + statusRest; - returnEvent(event); +// 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 becc00a..00b47f4 100644 --- a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp @@ -129,10 +129,10 @@ void SCXMLIOProcessor::send(const SendRequest& req) { boost::shared_ptr<InterpreterImpl> other = instances[sessionId].lock(); other->receive(reqCopy); } else { - LOG(ERROR) << "Can not send to scxml session " << sessionId << " - not known" << std::endl; - Event error("error.communication", Event::PLATFORM); + ERROR_COMMUNICATION(error, "Can not send to scxml session " + sessionId + " - not known"); error.sendid = reqCopy.sendid; _interpreter->receiveInternal(error); + } } else if (iequals(reqCopy.target, "#_parent")) { /** @@ -143,8 +143,7 @@ void SCXMLIOProcessor::send(const SendRequest& req) { if (_interpreter->_parentQueue != NULL) { _interpreter->_parentQueue->push(reqCopy); } else { - LOG(ERROR) << "Can not send to parent, we were not invoked" << std::endl; - Event error("error.communication", Event::PLATFORM); + ERROR_COMMUNICATION(error, "Can not send to parent, we were not invoked or no parent queue is set"); error.sendid = reqCopy.sendid; _interpreter->receiveInternal(error); } @@ -167,8 +166,7 @@ void SCXMLIOProcessor::send(const SendRequest& req) { LOG(ERROR) << "Exception caught while sending event to invoker " << invokeId; } } else { - LOG(ERROR) << "Can not send to invoked component '" << invokeId << "', no such invokeId" << std::endl; - Event error("error.communication", Event::PLATFORM); + ERROR_COMMUNICATION(error, "Can not send to invoked component '" + invokeId + "', no such invokeId"); error.sendid = reqCopy.sendid; _interpreter->receiveInternal(error); } @@ -177,8 +175,7 @@ void SCXMLIOProcessor::send(const SendRequest& req) { if (target.isAbsolute()) { BasicHTTPIOProcessor::send(reqCopy); } else { - LOG(ERROR) << "Not sure what to make of the target '" << reqCopy.target << "' - raising error" << std::endl; - Event error("error.execution", Event::PLATFORM); + ERROR_EXECUTION(error, "Not sure what to make of the target '" + reqCopy.target + "' - raising error"); error.sendid = reqCopy.sendid; // test 159 still fails // _interpreter->receiveInternal(error); diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp index 3bce169..fea97d8 100644 --- a/src/uscxml/transform/ChartToFSM.cpp +++ b/src/uscxml/transform/ChartToFSM.cpp @@ -972,9 +972,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t for (int i = 0; i < transitions.size(); i++) { if (HAS_ATTR(transitions[i], "eventexpr")) { - Event e("error.execution", Event::PLATFORM); - e.data.compound["cause"] = "Cannot flatten document with eventexpr attributes"; - throw e; + ERROR_EXECUTION_THROW("Cannot flatten document with eventexpr attributes"); } if (HAS_ATTR(transitions[i], "event")) { foundWithEvent = true; |