summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-03 19:15:07 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-03 19:15:07 (GMT)
commit2c1de149e0dbbf4e542a88affa2dae391c0c5ff6 (patch)
tree002201eeea3c913495b2f34aae76ff9d77d4e681
parent2ef535ff30882be189ac0937096d9f0f51d5723a (diff)
downloaduscxml-2c1de149e0dbbf4e542a88affa2dae391c0c5ff6.zip
uscxml-2c1de149e0dbbf4e542a88affa2dae391c0c5ff6.tar.gz
uscxml-2c1de149e0dbbf4e542a88affa2dae391c0c5ff6.tar.bz2
More bug fixes and some comments on the tests
-rw-r--r--README.md33
-rw-r--r--src/uscxml/Interpreter.cpp200
-rw-r--r--src/uscxml/Interpreter.h1
-rw-r--r--src/uscxml/Message.h153
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp32
5 files changed, 177 insertions, 242 deletions
diff --git a/README.md b/README.md
index ddbc8ee..679c947 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,39 @@ the respective build-process.
<b>[Results](http://uscxml.tk.informatik.tu-darmstadt.de/cdash/index.php?project=uscxml)</b> for continuous testing of the
[W3C IRP tests](http://www.w3.org/Voice/2013/scxml-irp/) for SCXML and some platform tests.
+<table>
+ <tr><th>Test#</th><th>Status</th><th>Comment</th></tr>
+ <tr><td><tt>178</tt></td><td><tt>Failed / Won't&nbsp;fix</tt></td>
+ <td>A manual test that relies on an unspecified _event.raw attribute</td>
+ <tr><td><tt>230</tt></td><td><tt>False report</tt></td>
+ <td>A manual test that is not actually failing but does not end in a state called <tt>pass</tt></td>
+ <tr><td><tt>250</tt></td><td><tt>False report</tt></td>
+ <td>A manual test that is not actually failing but does not end in a state called <tt>pass</tt></td>
+ <tr><td><tt>301</tt></td><td><tt>Failed</tt></td>
+ <td><i>"If the script can not be downloaded within a platform-specific timeout interval, the document
+ is considered non-conformant, and the platform must reject it"</i> -- USCXML will try to evaluate the
+ rest of the document nevertheless.</td>
+ </tr>
+ <tr><td><tt>307</tt></td><td><tt>False report</tt></td>
+ <td>A manual test that is not actually failing but does not end in a state called <tt>pass</tt></td>
+ <tr><td><tt>329</tt></td><td><tt>Failed / Won't&nbsp;fix</tt></td>
+ <td>Tests that <tt>_event</tt> cannot be assigned, but I like to add attributes to _event to have a
+ scope that only lasts for one event. Will raise the issue on the ML.</td>
+ <tr><td><tt>333</tt></td><td><tt>Failed / Won't&nbsp;fix</tt></td>
+ <td><i>"sendid [...] Otherwise it must leave it blank."</i> -- USCXML sets this to the empty string instead of <tt>null</tt>.</td>
+ <tr><td><tt>335</tt></td><td><tt>Failed / Won't&nbsp;fix</tt></td>
+ <td><i>"origin [...] For internal and platform events, the Processor must leave this field blank."</i> -- USCXML sets this to the empty string instead of <tt>null</tt>.</td>
+ <tr><td><tt>337</tt></td><td><tt>Failed / Won't&nbsp;fix</tt></td>
+ <td><i>"origintype [...] For internal and platform events, the Processor must leave this field blank."</i> -- USCXML sets this to the empty string instead of <tt>null</tt>.</td>
+ <tr><td><tt>339</tt></td><td><tt>Failed / Won't&nbsp;fix</tt></td>
+ <td><i>"invokeid [...] Otherwise it must leave it blank."</i> -- USCXML sets this to the empty string instead of <tt>null</tt>.</td>
+ <tr><td><tt>346</tt></td><td><tt>Failed / Won't&nbsp;fix</tt></td>
+ <td><i>"test that any attempt to change the value of a system variable causes error.execution to be raised."</i> -- I like to edit _event.</td>
+
+</table>
+
+
+
## License
uSCXML itself is distributed under the Simplified BSD license as in, do not sue us and do
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 4700056..e17b760 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -23,6 +23,18 @@
#define VERBOSE 0
+#define CATCH_AND_DISTRIBUTE(msg) \
+catch (Event e) {\
+ LOG(ERROR) << msg << std::endl << e << std::endl;\
+ if (rethrow) {\
+ throw(e);\
+ } else {\
+ e.name = "error.execution";\
+ e.type = Event::PLATFORM;\
+ _internalQueue.push_back(e);\
+ }\
+}
+
namespace uscxml {
using namespace Arabica::XPath;
@@ -356,54 +368,12 @@ void Interpreter::internalDoneSend(const Arabica::DOM::Node<std::string>& state)
if (doneDatas.size() > 0) {
// only process first donedata element
Arabica::DOM::Node<std::string> doneData = doneDatas[0];
- NodeList<std::string> doneChilds = doneData.getChildNodes();
- for (int i = 0; i < doneChilds.getLength(); i++) {
- if (doneChilds.item(i).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (boost::iequals(TAGNAME(doneChilds.item(i)), _xmlNSPrefix + "param")) {
- try {
- if (!HAS_ATTR(doneChilds.item(i), "name")) {
- LOG(ERROR) << "param element is missing name attribut";
- continue;
- }
- std::string paramValue;
- if (HAS_ATTR(doneChilds.item(i), "expr") && _dataModel) {
- std::string expr = _dataModel.evalAsString(ATTR(doneChilds.item(i), "expr"));
- paramValue = _dataModel.evalAsString(expr);
- } else if(HAS_ATTR(doneChilds.item(i), "location") && _dataModel) {
- paramValue = _dataModel.evalAsString(ATTR(doneChilds.item(i), "location"));
- } else {
- LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
- continue;
- }
- /// test 294
- event.data.compound[ATTR(doneChilds.item(i), "name")] = paramValue;
- } catch (Event e) {
- e.name = "error.execution";
- _internalQueue.push_back(e);
- }
- }
- if (boost::iequals(TAGNAME(doneChilds.item(i)), _xmlNSPrefix + "content")) {
- if (HAS_ATTR(doneChilds.item(i), "expr")) {
- try {
- if (_dataModel) {
- /// test 294
- event.data = Data(_dataModel.evalAsString(ATTR(doneChilds.item(i), "expr")), Data::VERBATIM);
- } else {
- LOG(ERROR) << "content element has expr attribute but no datamodel is specified.";
- }
- } catch (Event e) {
- e.name = "error.execution";
- _internalQueue.push_back(e);
- }
- } else if (doneChilds.item(i).hasChildNodes()) {
- event.data = Data(doneChilds.item(i).getFirstChild().getNodeValue(), Data::VERBATIM);
- } else {
- LOG(ERROR) << "content element does not specify any content.";
- }
-
- }
- }
+ processParamChilds(doneData, event.params);
+ Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", doneDatas[0]);
+ if (contents.size() > 1)
+ LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
+ if (contents.size() > 0)
+ processContentElement(contents[0], event.dom, event.content);
}
event.name = "done.state." + ATTR(stateElem.getParentNode(), "id"); // parent?!
@@ -465,6 +435,38 @@ void Interpreter::processContentElement(const Arabica::DOM::Node<std::string>& c
}
}
+void Interpreter::processParamChilds(const Arabica::DOM::Node<std::string>& element, std::multimap<std::string, std::string>& params) {
+ NodeSet<std::string> paramElems = filterChildElements(_xmlNSPrefix + "param", element);
+ try {
+ for (int i = 0; i < paramElems.size(); i++) {
+ if (!HAS_ATTR(paramElems[i], "name")) {
+ LOG(ERROR) << "param element is missing name attribute";
+ continue;
+ }
+ std::string paramValue;
+ if (HAS_ATTR(paramElems[i], "expr") && _dataModel) {
+ paramValue = _dataModel.evalAsString(ATTR(paramElems[i], "expr"));
+ } else if(HAS_ATTR(paramElems[i], "location") && _dataModel) {
+ paramValue = _dataModel.evalAsString(ATTR(paramElems[i], "location"));
+ } else {
+ LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
+ continue;
+ }
+ std::string paramKey = ATTR(paramElems[i], "name");
+ params.insert(std::make_pair(paramKey, paramValue));
+ }
+ } catch(Event e) {
+ LOG(ERROR) << "Syntax error while processing params:" << std::endl << e << std::endl;
+ // test 343
+ std::multimap<std::string, std::string>::iterator paramIter = params.begin();
+ while(paramIter != params.end()) {
+ params.erase(paramIter++);
+ }
+ e.name = "error.execution";
+ _internalQueue.push_back(e);
+ }
+}
+
void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
SendRequest sendReq;
// test 331
@@ -585,28 +587,7 @@ void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
try {
// params
- NodeSet<std::string> params = filterChildElements(_xmlNSPrefix + "param", element);
- for (int i = 0; i < params.size(); i++) {
- if (!HAS_ATTR(params[i], "name")) {
- LOG(ERROR) << "param element is missing name attribute";
- continue;
- }
- std::string paramValue;
- if (HAS_ATTR(params[i], "expr") && _dataModel) {
- paramValue = _dataModel.evalAsString(ATTR(params[i], "expr"));
- } else if(HAS_ATTR(params[i], "location") && _dataModel) {
- paramValue = _dataModel.evalAsString(ATTR(params[i], "location"));
- } else {
- LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
- continue;
- }
- std::string paramKey = ATTR(params[i], "name");
- // use lower case parameter name in params - this is at least something to think about again
- std::string lcParamKey = paramKey;
- boost::algorithm::to_lower(lcParamKey);
- sendReq.params.insert(std::make_pair(lcParamKey, paramValue));
- sendReq.data.compound[paramKey] = Data(paramValue, Data::VERBATIM);
- }
+ processParamChilds(element, sendReq.params);
} catch (Event e) {
LOG(ERROR) << "Syntax error in send element param expr:" << std::endl << e << std::endl;
return;
@@ -760,30 +741,7 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
}
// params
- NodeSet<std::string> params = filterChildElements(_xmlNSPrefix + "param", element);
- for (int i = 0; i < params.size(); i++) {
- if (!HAS_ATTR(params[i], "name")) {
- LOG(ERROR) << "param element is missing name attribut";
- continue;
- }
- std::string paramValue;
- if (HAS_ATTR(params[i], "expr")) {
- if (_dataModel) {
- paramValue = _dataModel.evalAsString(ATTR(params[i], "expr"));
- } else {
- LOG(ERROR) << "Cannot use param expr without a datamodel!";
- }
- } else if(HAS_ATTR(params[i], "location") && _dataModel) {
- paramValue = _dataModel.evalAsString(ATTR(params[i], "location"));
- } else {
- LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
- continue;
- }
- std::string paramKey = ATTR(params[i], "name");
- //boost::algorithm::to_lower(paramKey);
- invokeReq.params.insert(std::make_pair(paramKey, paramValue));
-
- }
+ processParamChilds(element, invokeReq.params);
// content
try {
@@ -911,6 +869,8 @@ bool Interpreter::hasConditionMatch(const Arabica::DOM::Node<std::string>& condi
return _dataModel.evalAsBool(ATTR(conditional, "cond"));
} catch (Event e) {
LOG(ERROR) << "Syntax error in cond attribute of " << TAGNAME(conditional) << " element:" << std::endl << e << std::endl;
+ e.name = "error.execution";
+ _internalQueue.push_back(e);
return false;
}
}
@@ -1000,12 +960,8 @@ void Interpreter::executeContent(const Arabica::DOM::Node<std::string>& content,
uint32_t iterations = 0;
try {
iterations = _dataModel.getLength(array);
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in array attribute of foreach element:" << std::endl << e << std::endl;
- if (rethrow)
- throw e;
- return;
}
+ CATCH_AND_DISTRIBUTE("Syntax error in array attribute of foreach element:")
try {
_dataModel.pushContext(); // copy old and enter new context
for (uint32_t iteration = 0; iteration < iterations; iteration++) {
@@ -1026,12 +982,8 @@ void Interpreter::executeContent(const Arabica::DOM::Node<std::string>& content,
executeContent(content.getChildNodes(), true);
}
_dataModel.popContext(); // leave stacked context
- } catch (Event e) {
- _dataModel.popContext(); // leave stacked context even when exception was thrown
- LOG(ERROR) << "Syntax error in foreach element:" << std::endl << e << std::endl;
- if (rethrow)
- throw e;
}
+ CATCH_AND_DISTRIBUTE("Syntax error in foreach element:")
} else {
LOG(ERROR) << "Expected array and item attributes with foreach element!" << std::endl;
}
@@ -1045,11 +997,8 @@ void Interpreter::executeContent(const Arabica::DOM::Node<std::string>& content,
if (_dataModel) {
try {
std::cout << _dataModel.evalAsString(logElem.getAttribute("expr")) << std::endl;
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in expr attribute of log element:" << std::endl << e << std::endl;
- if (rethrow)
- throw e;
}
+ CATCH_AND_DISTRIBUTE("Syntax error in expr attribute of log element:")
} else {
if (logElem.hasAttribute("label"))
std::cout << std::endl;
@@ -1062,18 +1011,12 @@ void Interpreter::executeContent(const Arabica::DOM::Node<std::string>& content,
if (!_dataModel.isDeclared(ATTR(content, "location"))) {
// test 286, 331
LOG(ERROR) << "Assigning to undeclared location '" << ATTR(content, "location") << "' not allowed." << std::endl;
- Event e("error.execution", Event::PLATFORM);
- _internalQueue.push_back(e);
- throw e;
- return;
+ throw Event("error.execution", Event::PLATFORM);
} else {
_dataModel.assign(ATTR(content, "location"), ATTR(content, "expr"));
}
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in attributes of assign element:" << std::endl << e << std::endl;
- if (rethrow)
- throw e;
}
+ CATCH_AND_DISTRIBUTE("Syntax error in attributes of assign element:")
}
} else if (boost::iequals(TAGNAME(content), _xmlNSPrefix + "validate")) {
// --- VALIDATE --------------------------
@@ -1106,22 +1049,16 @@ void Interpreter::executeContent(const Arabica::DOM::Node<std::string>& content,
try {
_dataModel.eval(srcContent.str());
- } catch (Event e) {
- LOG(ERROR) << "Syntax error while executing script element from '" << ATTR(content, "src") << "':" << std::endl << e << std::endl;
- if (rethrow)
- throw e;
}
+ 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
if (content.getFirstChild().getNodeType() == Node_base::TEXT_NODE) {
try {
_dataModel.eval(content.getFirstChild().getNodeValue());
- } catch (Event e) {
- LOG(ERROR) << "Syntax error while executing script element" << std::endl << e << std::endl;
- if (rethrow)
- throw e;
}
+ CATCH_AND_DISTRIBUTE("Syntax error while executing script element")
}
}
}
@@ -1143,12 +1080,8 @@ void Interpreter::executeContent(const Arabica::DOM::Node<std::string>& content,
}
_sendQueue->cancelEvent(sendId);
- } catch (Event e) {
- LOG(ERROR) << "Syntax error while executing cancel element" << std::endl << e << std::endl;
- if (rethrow)
- throw e;
}
-
+ CATCH_AND_DISTRIBUTE("Syntax error while executing cancel element")
} else if (boost::iequals(TAGNAME(content), _xmlNSPrefix + "invoke")) {
// --- INVOKE --------------------------
} else {
@@ -1368,24 +1301,21 @@ Arabica::XPath::NodeSet<std::string> Interpreter::getInitialStates(Arabica::DOM:
assert(isCompound(state) || isParallel(state));
- Arabica::XPath::NodeSet<std::string> initialStates;
-
// initial attribute at element
Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state;
if (stateElem.hasAttribute("initial")) {
return getStates(tokenizeIdRefs(stateElem.getAttribute("initial")));
}
- Arabica::XPath::NodeSet<std::string> initStates;
-
// initial element as child - but not the implicit generated one
NodeSet<std::string> initElems = filterChildElements(_xmlNSPrefix + "initial", state);
if(initElems.size() == 1 && !boost::iequals(ATTR(initElems[0], "generated"), "true")) {
- initStates.push_back(initialStates[0]);
- return initStates;
+ NodeSet<std::string> initTrans = filterChildElements(_xmlNSPrefix + "transition", initElems[0]);
+ return getTargetStates(initTrans[0]);
}
// first child state
+ Arabica::XPath::NodeSet<std::string> initStates;
NodeList<std::string> childs = state.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
if (isState(childs.item(i))) {
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index 0eac6fb..4bac414 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -287,6 +287,7 @@ 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, std::string& text);
+ void processParamChilds(const Arabica::DOM::Node<std::string>& element, std::multimap<std::string, std::string>& params);
void send(const Arabica::DOM::Node<std::string>& element);
void invoke(const Arabica::DOM::Node<std::string>& element);
diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h
index cb7196a..19adf99 100644
--- a/src/uscxml/Message.h
+++ b/src/uscxml/Message.h
@@ -172,51 +172,6 @@ public:
return ss.str();
}
-#ifdef SWIGIMPORTED
-protected:
-#endif
-
- std::string name;
- Type type;
- std::string origin;
- std::string origintype;
- Arabica::DOM::Document<std::string> dom;
- std::string sendid;
- std::string invokeid;
- Data data;
- std::string content;
-
-#ifndef SWIG
- friend std::ostream& operator<< (std::ostream& os, const Event& event);
-#endif
-};
-
-class InvokeRequest : public Event {
-public:
- InvokeRequest(Event event) : Event(event) {}
- InvokeRequest() {}
-
- std::string getType() {
- return type;
- }
- void setType(const std::string& type) {
- this->type = type;
- }
-
- std::string getSource() {
- return src;
- }
- void setSource(const std::string& src) {
- this->src = src;
- }
-
- bool isAutoForwarded() {
- return autoForward;
- }
- void setAutoForwarded(bool autoForward) {
- this->autoForward = autoForward;
- }
-
#ifdef SWIG
/// TODO: Do we want to set namelist and params as well?
std::map<std::string, std::string> getNameList() {
@@ -263,6 +218,57 @@ public:
}
#endif
+
+#ifdef SWIGIMPORTED
+protected:
+#endif
+
+ std::string name;
+ Type type;
+ std::string origin;
+ std::string origintype;
+ Arabica::DOM::Document<std::string> dom;
+ std::string sendid;
+ std::string invokeid;
+ Data data;
+ std::string content;
+ std::map<std::string, std::string> namelist;
+ std::multimap<std::string, std::string> params;
+
+ typedef std::multimap<std::string, std::string> params_t;
+ typedef std::map<std::string, std::string> namelist_t;
+
+#ifndef SWIG
+ friend std::ostream& operator<< (std::ostream& os, const Event& event);
+#endif
+};
+
+class InvokeRequest : public Event {
+public:
+ InvokeRequest(Event event) : Event(event) {}
+ InvokeRequest() {}
+
+ std::string getType() {
+ return type;
+ }
+ void setType(const std::string& type) {
+ this->type = type;
+ }
+
+ std::string getSource() {
+ return src;
+ }
+ void setSource(const std::string& src) {
+ this->src = src;
+ }
+
+ bool isAutoForwarded() {
+ return autoForward;
+ }
+ void setAutoForwarded(bool autoForward) {
+ this->autoForward = autoForward;
+ }
+
static InvokeRequest fromXML(const std::string& xmlString);
Arabica::DOM::Document<std::string> toDocument();
std::string toXMLString() {
@@ -277,11 +283,6 @@ protected:
std::string type;
std::string src;
bool autoForward;
- std::map<std::string, std::string> namelist;
- std::multimap<std::string, std::string> params;
-
- typedef std::multimap<std::string, std::string> params_t;
- typedef std::map<std::string, std::string> namelist_t;
#ifndef SWIG
friend std::ostream& operator<< (std::ostream& os, const InvokeRequest& sendReq);
@@ -315,52 +316,6 @@ public:
this->delayMs = delayMs;
}
-#ifdef SWIG
- /// TODO: Do we want to set namelist and params as well?
- std::map<std::string, std::string> getNameList() {
- return namelist;
- }
-
- const std::vector<std::string> getNameListKeys() {
- std::set<std::string> keys;
- namelist_t::const_iterator nameListIter = namelist.begin();
- while (nameListIter != namelist.end()) {
- keys.insert(nameListIter->first);
- nameListIter++;
- }
- return std::vector<std::string>(keys.begin(), keys.end());
- }
-
- // substitute multimap by map with vectors for language bindings
- std::map<std::string, std::vector<std::string> > getParams() {
- std::map<std::string, std::vector<std::string> > paramsMap;
- params_t::iterator paramIter = params.begin();
- while(paramIter != params.end()) {
- paramsMap[paramIter->first].push_back(paramIter->second);
- paramIter++;
- }
- return paramsMap;
- }
-
- const std::vector<std::string> getParamKeys() {
- std::set<std::string> keys;
- params_t::iterator paramIter = params.begin();
- while(paramIter != params.end()) {
- keys.insert(paramIter->first);
- paramIter++;
- }
- return std::vector<std::string>(keys.begin(), keys.end());
- }
-
-#else
- std::map<std::string, std::string>& getNameList() {
- return namelist;
- }
- std::multimap<std::string, std::string>& getParams() {
- return params;
- }
-#endif
-
static SendRequest fromXML(const std::string& xmlString);
Arabica::DOM::Document<std::string> toDocument();
std::string toXMLString() {
@@ -377,12 +332,6 @@ protected:
std::string type;
uint32_t delayMs;
- std::map<std::string, std::string> namelist;
- std::multimap<std::string, std::string> params;
-
- typedef std::map<std::string, std::string> namelist_t;
- typedef std::multimap<std::string, std::string> params_t;
-
#ifndef SWIG
friend std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq);
#endif
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
index c24e3ec..e86472b 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
@@ -143,6 +143,7 @@ void V8DataModel::setEvent(const Event& event) {
eventObj->SetInternalField(0, Arabica::DOM::V8DOM::toExternal(privData));
eventObj.MakeWeak(0, Arabica::DOM::V8SCXMLEvent::jsDestructor);
if (event.dom) {
+ // _event.data is a DOM document
v8::Handle<v8::Function> retCtor = Arabica::DOM::V8Document::getTmpl()->GetFunction();
v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance());
@@ -153,11 +154,33 @@ void V8DataModel::setEvent(const Event& event) {
retObj->SetInternalField(0, Arabica::DOM::V8DOM::toExternal(retPrivData));
retObj.MakeWeak(0, Arabica::DOM::V8Document::jsDestructor);
- eventObj->Set(v8::String::New("data"), retObj); // set data part of _event
+ eventObj->Set(v8::String::New("data"), retObj);
} else if (event.content.length() > 0) {
- eventObj->Set(v8::String::New("data"), v8::String::New(event.content.c_str())); // set data part of _event
+ // _event.data is a string
+ eventObj->Set(v8::String::New("data"), v8::String::New(event.content.c_str()));
} else {
- eventObj->Set(v8::String::New("data"), getDataAsValue(event.data)); // set data part of _event
+ // _event.data is KVP
+ Event eventCopy(event);
+ if (!eventCopy.params.empty()) {
+ Event::params_t::iterator paramIter = eventCopy.params.begin();
+ while(paramIter != eventCopy.params.end()) {
+ eventCopy.data.compound[paramIter->first] = Data(paramIter->second, Data::VERBATIM);
+ paramIter++;
+ }
+ }
+ if (!eventCopy.namelist.empty()) {
+ Event::namelist_t::iterator nameListIter = eventCopy.namelist.begin();
+ while(nameListIter != eventCopy.namelist.end()) {
+ eventCopy.data.compound[nameListIter->first] = Data(nameListIter->second, Data::VERBATIM);
+ nameListIter++;
+ }
+ }
+ if (eventCopy.data.compound.size() > 0) {
+ eventObj->Set(v8::String::New("data"), getDataAsValue(eventCopy.data)); // set data part of _event
+ } else {
+ // test 343
+ eventObj->Set(v8::String::New("data"), v8::Undefined()); // set data part of _event
+ }
}
global->Set(v8::String::New("_event"), eventObj);
}
@@ -296,7 +319,6 @@ uint32_t V8DataModel::getLength(const std::string& expr) {
exceptionEvent.name = "error.execution";
exceptionEvent.data.compound["exception"] = Data("'" + expr + "' does not evaluate to an array.", Data::VERBATIM);;
- _interpreter->receiveInternal(exceptionEvent);
throw(exceptionEvent);
}
@@ -438,7 +460,7 @@ void V8DataModel::throwExceptionEvent(const v8::TryCatch& tryCatch) {
}
- _interpreter->receiveInternal(exceptionEvent);
+// _interpreter->receiveInternal(exceptionEvent);
throw(exceptionEvent);
}