diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-04-07 17:08:46 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-04-07 17:08:46 (GMT) |
commit | f13848cab284839c2f6abd39ef38dd18692a50cf (patch) | |
tree | 8de4b167374511cc2f7a9d89c2efb3f77ca3235d /src | |
parent | 46d089f8642501cf2ffc4a531add0a3a8eaa268e (diff) | |
download | uscxml-f13848cab284839c2f6abd39ef38dd18692a50cf.zip uscxml-f13848cab284839c2f6abd39ef38dd18692a50cf.tar.gz uscxml-f13848cab284839c2f6abd39ef38dd18692a50cf.tar.bz2 |
Even more conformance fixes
Diffstat (limited to 'src')
-rw-r--r-- | src/uscxml/Interpreter.cpp | 77 | ||||
-rw-r--r-- | src/uscxml/Interpreter.h | 22 | ||||
-rw-r--r-- | src/uscxml/Message.h | 7 | ||||
-rw-r--r-- | src/uscxml/interpreter/InterpreterDraft6.cpp | 3 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp | 5 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp | 13 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h | 4 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEventCustom.cpp | 11 | ||||
-rw-r--r-- | src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp | 2 | ||||
-rw-r--r-- | src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp | 38 |
10 files changed, 116 insertions, 66 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index ee1a3b9..9d6b764 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -349,7 +349,15 @@ void InterpreterImpl::initializeData(const Node<std::string>& data) { if (HAS_ATTR(data, "expr")) { // expression given directly std::string value = ATTR(data, "expr"); - _dataModel.assign(ATTR(data, "id"), value); + try { + _dataModel.assign(ATTR(data, "id"), value); + } catch (Event e) { + LOG(ERROR) << "Syntax error in data element:" << std::endl << e << std::endl; + /// test 277 + /// todo: if the identifier is invalid we'll raise to error events + receiveInternal(e); + _dataModel.assign(ATTR(data, "id"), "undefined"); + } return; } @@ -376,7 +384,14 @@ void InterpreterImpl::initializeData(const Node<std::string>& data) { inputSource.setByteStream(ssPtr); Arabica::SAX2DOM::Parser<std::string> parser; if(parser.parse(inputSource) && parser.getDocument()) { - _dataModel.assign(ATTR(data, "id"), parser.getDocument()); + try { + _dataModel.assign(ATTR(data, "id"), parser.getDocument()); + return; + } catch (Event e) { + LOG(ERROR) << "Syntax error in data element:" << std::endl << e << std::endl; + receiveInternal(e); + _dataModel.assign(ATTR(data, "id"), "undefined"); + } return; } } else if (data.hasChildNodes()) { @@ -443,7 +458,7 @@ void InterpreterImpl::initializeData(const Node<std::string>& data) { void InterpreterImpl::normalize(Arabica::DOM::Element<std::string>& scxml) { // TODO: Resolve XML includes - + // make sure every state has an id and set isFirstEntry to true Arabica::XPath::NodeSet<std::string> states = _xpath.evaluate("//" + _xpathPrefix + "state", _scxml).asNodeSet(); for (int i = 0; i < states.size(); i++) { @@ -507,6 +522,14 @@ void InterpreterImpl::receiveInternal(const Event& event) { _internalQueue.push_back(event); } +void InterpreterImpl::receive(const Event& event, bool toFront) { + std::cout << "receive: " << event.name << std::endl; + if (toFront) { + _externalQueue.push_front(event); + } else { + _externalQueue.push(event); + } +} void InterpreterImpl::internalDoneSend(const Arabica::DOM::Node<std::string>& state) { if (!isState(state)) @@ -688,6 +711,8 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { sendReq.sendid = ATTR(getParentState(element), "id") + "." + getUUID(); if (HAS_ATTR(element, "idlocation") && _dataModel) { _dataModel.assign(ATTR(element, "idlocation"), "'" + sendReq.sendid + "'"); + } else { + sendReq.hideSendId = true; } } } catch (Event e) { @@ -777,37 +802,30 @@ void InterpreterImpl::delayedSend(void* userdata, std::string eventName) { InterpreterImpl* INSTANCE = data->first; SendRequest sendReq = data->second; - if (sendReq.target.length() == 0) { - /** - * If neither the 'target' nor the 'targetexpr' attribute is specified, the - * SCXML Processor must add the event will be added to the external event - * queue of the sending session. - */ - INSTANCE->_externalQueue.push(sendReq); + /** + * If neither the 'type' nor the 'typeexpr' is defined, the SCXML Processor + * must assume the default value of http://www.w3.org/TR/scxml/#SCXMLEventProcessor + */ + if (sendReq.type.length() == 0) + sendReq.type = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; + + IOProcessor ioProc = INSTANCE->getIOProcessor(sendReq.type); + if (ioProc) { + try { + ioProc.send(sendReq); + } catch(...) { + LOG(ERROR) << "Exception caught while sending event to ioprocessor " << sendReq.type; + } } else { /** - * If neither the 'type' nor the 'typeexpr' is defined, the SCXML Processor - * must assume the default value of http://www.w3.org/TR/scxml/#SCXMLEventProcessor + * If the SCXML Processor does not support the type that is specified, it + * must place the event error.execution on the internal event queue. */ - if (sendReq.type.length() == 0) - sendReq.type = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; - IOProcessor ioProc = INSTANCE->getIOProcessor(sendReq.type); - if (ioProc) { - try { - ioProc.send(sendReq); - } catch(...) { - LOG(ERROR) << "Exception caught while sending event to ioprocessor " << sendReq.type; - } - } else { - /** - * 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); + Event exceptionEvent("error.execution", Event::PLATFORM); // exceptionEvent.sendid = sendReq.sendid; - INSTANCE->receiveInternal(exceptionEvent); - } + INSTANCE->receiveInternal(exceptionEvent); } + assert(INSTANCE->_sendIds.find(sendReq.sendid) != INSTANCE->_sendIds.end()); INSTANCE->_sendIds.erase(sendReq.sendid); } @@ -1246,6 +1264,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont } void InterpreterImpl::returnDoneEvent(const Arabica::DOM::Node<std::string>& state) { + std::cout << state << std::endl; if (_parentQueue != NULL) { Event done; done.name = "done.invoke." + _sessionId; diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index 9be85ff..2a63604 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -66,9 +66,9 @@ public: }; enum Capabilities { - CAN_NOTHING = 0, - CAN_BASIC_HTTP = 1, - CAN_GENERIC_HTTP = 2, + CAN_NOTHING = 0, + CAN_BASIC_HTTP = 1, + CAN_GENERIC_HTTP = 2, }; class InterpreterImpl : public boost::enable_shared_from_this<InterpreterImpl> { @@ -139,14 +139,8 @@ public: return ""; } - void inline receiveInternal(const Event& event); - void receive(const Event& event, bool toFront = false) { - if (toFront) { - _externalQueue.push_front(event); - } else { - _externalQueue.push(event); - } - } + void receiveInternal(const Event& event); + void receive(const Event& event, bool toFront = false); Event getCurrentEvent() { return _currEvent; @@ -553,7 +547,7 @@ public: boost::shared_ptr<InterpreterImpl> getImpl() { return _impl; } - + static std::map<std::string, boost::weak_ptr<InterpreterImpl> > getInstances() { tthread::lock_guard<tthread::recursive_mutex> lock(_instanceMutex); std::map<std::string, boost::weak_ptr<InterpreterImpl> >::iterator instIter = _instances.begin(); @@ -566,9 +560,9 @@ public: } return _instances; } - + #endif - + protected: boost::shared_ptr<InterpreterImpl> _impl; static std::map<std::string, boost::weak_ptr<InterpreterImpl> > _instances; diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h index 72a2a99..9f5e8e2 100644 --- a/src/uscxml/Message.h +++ b/src/uscxml/Message.h @@ -94,9 +94,9 @@ public: PLATFORM = 3 }; - Event() : type(INTERNAL) {} - Event(const std::string& name, Type type = INTERNAL) : name(name), type(type) {} - Event(const Arabica::DOM::Node<std::string>& xmlString) : type(INTERNAL) {}; + Event() : type(INTERNAL), hideSendId(false) {} + Event(const std::string& name, Type type = INTERNAL) : name(name), type(type), hideSendId(false) {} + Event(const Arabica::DOM::Node<std::string>& xmlString) : type(INTERNAL), hideSendId(false) {}; bool operator< (const Event& other) const { return this < &other; } @@ -229,6 +229,7 @@ protected: std::string origintype; Arabica::DOM::Document<std::string> dom; std::string sendid; + bool hideSendId; std::string invokeid; Data data; std::string content; diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index 3c97805..3c4a699 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -63,8 +63,9 @@ void InterpreterDraft6::interpret() { // executeGlobalScriptElements NodeSet<std::string> globalScriptElems = filterChildElements(_xmlNSPrefix + "script", _scxml); for (unsigned int i = 0; i < globalScriptElems.size(); i++) { - if (_dataModel) + if (_dataModel) { executeContent(globalScriptElems[i]); + } } NodeSet<std::string> initialTransitions; diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index e653607..fff3f9b 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -143,11 +143,13 @@ void V8DataModel::setEvent(const Event& event) { privData->dom = _dom; eventObj->SetInternalField(0, Arabica::DOM::V8DOM::toExternal(privData)); eventObj.MakeWeak(0, Arabica::DOM::V8SCXMLEvent::jsDestructor); + if (event.dom) { eventObj->Set(v8::String::New("data"), getDocumentAsValue(event.dom)); } else if (event.content.length() > 0) { // _event.data is a string eventObj->Set(v8::String::New("data"), v8::String::New(event.content.c_str())); +// eventObj->Set(v8::String::New("data"), v8::Undefined()); } else { // _event.data is KVP Event eventCopy(event); @@ -168,10 +170,11 @@ void V8DataModel::setEvent(const Event& event) { if (eventCopy.data.compound.size() > 0) { eventObj->Set(v8::String::New("data"), getDataAsValue(eventCopy.data)); // set data part of _event } else { - // test 343 + // test 343 / test 488 eventObj->Set(v8::String::New("data"), v8::Undefined()); // set data part of _event } } + // we cannot make _event v8::ReadOnly as it will ignore subsequent setEvents global->Set(v8::String::New("_event"), eventObj); } diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp index fec2a94..86fcfef 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp @@ -18,6 +18,8 @@ v8::Handle<v8::Value> V8SCXMLEvent::originAttrGetter(v8::Local<v8::String> prope v8::Local<v8::Object> self = info.Holder(); struct V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEventPrivate >(self->GetInternalField(0)); + if (privData->nativeObj->origin.length() == 0) + return v8::Undefined(); return v8::String::New(privData->nativeObj->origin.c_str()); } @@ -25,6 +27,8 @@ v8::Handle<v8::Value> V8SCXMLEvent::origintypeAttrGetter(v8::Local<v8::String> p v8::Local<v8::Object> self = info.Holder(); struct V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEventPrivate >(self->GetInternalField(0)); + if (privData->nativeObj->origintype.length() == 0) + return v8::Undefined(); return v8::String::New(privData->nativeObj->origintype.c_str()); } @@ -48,17 +52,12 @@ v8::Handle<v8::Value> V8SCXMLEvent::domAttrGetter(v8::Local<v8::String> property } -v8::Handle<v8::Value> V8SCXMLEvent::sendidAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) { - v8::Local<v8::Object> self = info.Holder(); - struct V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEventPrivate >(self->GetInternalField(0)); - - return v8::String::New(privData->nativeObj->sendid.c_str()); -} - v8::Handle<v8::Value> V8SCXMLEvent::invokeidAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) { v8::Local<v8::Object> self = info.Holder(); struct V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEventPrivate >(self->GetInternalField(0)); + if (privData->nativeObj->invokeid.length() == 0) + return v8::Undefined(); return v8::String::New(privData->nativeObj->invokeid.c_str()); } bool V8SCXMLEvent::hasInstance(v8::Handle<v8::Value> value) { diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h index f17856a..e7dbacc 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h @@ -46,7 +46,7 @@ public: 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); static v8::Handle<v8::Value> domAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); - static v8::Handle<v8::Value> sendidAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); + static v8::Handle<v8::Value> sendidCustomAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); static v8::Handle<v8::Value> invokeidAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); static v8::Persistent<v8::FunctionTemplate> Tmpl; @@ -72,7 +72,7 @@ public: v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None)); instance->SetAccessor(v8::String::NewSymbol("dom"), V8SCXMLEvent::domAttrGetter, 0, v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None)); - instance->SetAccessor(v8::String::NewSymbol("sendid"), V8SCXMLEvent::sendidAttrGetter, 0, + instance->SetAccessor(v8::String::NewSymbol("sendid"), V8SCXMLEvent::sendidCustomAttrGetter, 0, v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None)); instance->SetAccessor(v8::String::NewSymbol("invokeid"), V8SCXMLEvent::invokeidAttrGetter, 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 05644b0..4eecb94 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEventCustom.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEventCustom.cpp @@ -5,7 +5,7 @@ namespace DOM { v8::Handle<v8::Value> V8SCXMLEvent::typeCustomAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) { v8::Local<v8::Object> self = info.Holder(); - V8SCXMLEvent::V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEvent::V8SCXMLEventPrivate >(self->GetInternalField(0)); + V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEventPrivate >(self->GetInternalField(0)); switch (privData->nativeObj->type) { case uscxml::Event::INTERNAL: @@ -23,5 +23,14 @@ v8::Handle<v8::Value> V8SCXMLEvent::typeCustomAttrGetter(v8::Local<v8::String> p return v8::String::New("unknown"); } +v8::Handle<v8::Value> V8SCXMLEvent::sendidCustomAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) { + v8::Local<v8::Object> self = info.Holder(); + V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEventPrivate >(self->GetInternalField(0)); + + if (privData->nativeObj->sendid.length() == 0 || privData->nativeObj->hideSendId) + return v8::Undefined(); + return v8::String::New(privData->nativeObj->sendid.c_str()); +} + } }
\ No newline at end of file diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp index 9ae62a8..7564f1d 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp @@ -120,7 +120,7 @@ void BasicHTTPIOProcessor::send(const SendRequest& req) { bool isLocal = false; std::string target; - if (req.target.length() > 0) { + if (req.target.length() > 0 && !boost::equals(req.target, _url)) { target = req.target; } else { isLocal = true; diff --git a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp index 3dabafe..288bfb7 100644 --- a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp @@ -71,10 +71,21 @@ void SCXMLIOProcessor::send(const SendRequest& req) { SendRequest reqCopy(req); // test 253 - reqCopy.origintype = "scxml"; + reqCopy.origintype = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; reqCopy.origin = _url; if (false) { + } else if(reqCopy.target.length() == 0) { + /** + * If neither the 'target' nor the 'targetexpr' attribute is specified, the + * SCXML Processor must add the event will be added to the external event + * queue of the sending session. + */ + + // test333 vs test351 +// reqCopy.sendid = ""; + // test 198 + _interpreter->receive(reqCopy); } else if (boost::iequals(reqCopy.target, "#_internal")) { /** * #_internal: If the target is the special term '#_internal', the Processor @@ -97,10 +108,10 @@ void SCXMLIOProcessor::send(const SendRequest& req) { other->receive(reqCopy); } else { LOG(ERROR) << "Can not send to scxml session " << sessionId << " - not known" << std::endl; - _interpreter->receiveInternal(Event("error.communication", Event::PLATFORM)); + Event error("error.communication", Event::PLATFORM); + error.sendid = reqCopy.sendid; + _interpreter->receiveInternal(error); } - - } else if (boost::iequals(reqCopy.target, "#_parent")) { /** * #_parent: If the target is the special term '#_parent', the Processor must @@ -111,9 +122,11 @@ void SCXMLIOProcessor::send(const SendRequest& req) { _interpreter->_parentQueue->push(reqCopy); } else { LOG(ERROR) << "Can not send to parent, we were not invoked" << std::endl; - _interpreter->receiveInternal(Event("error.communication", Event::PLATFORM)); + Event error("error.communication", Event::PLATFORM); + error.sendid = reqCopy.sendid; + _interpreter->receiveInternal(error); } - } else if (boost::starts_with(reqCopy.target, "#_") == 0) { + } else if (boost::starts_with(reqCopy.target, "#_")) { /** * #_invokeid: If the target is the special term '#_invokeid', where invokeid * is the invokeid of an SCXML session that the sending session has created @@ -130,9 +143,20 @@ void SCXMLIOProcessor::send(const SendRequest& req) { } } else { LOG(ERROR) << "Can not send to invoked component '" << invokeId << "', no such invokeId" << std::endl; - _interpreter->receiveInternal(Event("error.communication", Event::PLATFORM)); + Event error("error.communication", Event::PLATFORM); + error.sendid = reqCopy.sendid; + _interpreter->receiveInternal(error); } } else { + URL target(reqCopy.target); + 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.sendid = reqCopy.sendid; + _interpreter->receiveInternal(error); + } } } |