summaryrefslogtreecommitdiffstats
path: root/src/uscxml
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-07 17:08:46 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-07 17:08:46 (GMT)
commitf13848cab284839c2f6abd39ef38dd18692a50cf (patch)
tree8de4b167374511cc2f7a9d89c2efb3f77ca3235d /src/uscxml
parent46d089f8642501cf2ffc4a531add0a3a8eaa268e (diff)
downloaduscxml-f13848cab284839c2f6abd39ef38dd18692a50cf.zip
uscxml-f13848cab284839c2f6abd39ef38dd18692a50cf.tar.gz
uscxml-f13848cab284839c2f6abd39ef38dd18692a50cf.tar.bz2
Even more conformance fixes
Diffstat (limited to 'src/uscxml')
-rw-r--r--src/uscxml/Interpreter.cpp77
-rw-r--r--src/uscxml/Interpreter.h22
-rw-r--r--src/uscxml/Message.h7
-rw-r--r--src/uscxml/interpreter/InterpreterDraft6.cpp3
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp5
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp13
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h4
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEventCustom.cpp11
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp2
-rw-r--r--src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp38
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);
+ }
}
}