diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-03-30 16:08:37 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-03-30 16:08:37 (GMT) |
commit | 28014abf13ca64031b8b84dcf585ec4569881ab0 (patch) | |
tree | 9680223cdbd3adde5bd80d18f1b29ea3a0990e4f /src/uscxml/plugins/datamodel | |
parent | 2317f2bf8beb03c60463a9482dbef23540f5c1e0 (diff) | |
download | uscxml-28014abf13ca64031b8b84dcf585ec4569881ab0.zip uscxml-28014abf13ca64031b8b84dcf585ec4569881ab0.tar.gz uscxml-28014abf13ca64031b8b84dcf585ec4569881ab0.tar.bz2 |
Various bug fixes
- Removed scxml-test-framework related file
- Array operator with V8NodeList
- _event.data as DOM if content is XML
Diffstat (limited to 'src/uscxml/plugins/datamodel')
4 files changed, 140 insertions, 42 deletions
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index 407988e..4072862 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -1,6 +1,8 @@ #include "uscxml/Common.h" #include "V8DataModel.h" +#include "dom/V8DOM.h" #include "dom/V8Document.h" +#include "dom/V8Node.h" #include "dom/V8SCXMLEvent.h" #include "uscxml/Message.h" @@ -118,8 +120,23 @@ 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) { + v8::Handle<v8::Function> retCtor = Arabica::DOM::V8Document::getTmpl()->GetFunction(); + v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance()); - eventObj->Set(v8::String::New("data"), getDataAsValue(event.data)); // set data part of _event + struct Arabica::DOM::V8Document::V8DocumentPrivate* retPrivData = new Arabica::DOM::V8Document::V8DocumentPrivate(); + retPrivData->dom = privData->dom; + retPrivData->nativeObj = (Arabica::DOM::Document<std::string>*)&event.dom; + + 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 + } else if (event.content.length() > 0) { + eventObj->Set(v8::String::New("data"), v8::String::New(event.content.c_str())); // set data part of _event + } else { + eventObj->Set(v8::String::New("data"), getDataAsValue(event.data)); // set data part of _event + } global->Set(v8::String::New("_event"), eventObj); } @@ -247,9 +264,18 @@ bool V8DataModel::validate(const std::string& location, const std::string& schem uint32_t V8DataModel::getLength(const std::string& expr) { v8::Locker locker; v8::HandleScope handleScope; + v8::TryCatch tryCatch; v8::Context::Scope contextScope(_contexts.back()); - v8::Handle<v8::Array> result = evalAsValue(expr).As<v8::Array>(); - return result->Length(); + v8::Handle<v8::Value> result = evalAsValue(expr); + if (!result.IsEmpty() && result->IsArray()) + return result.As<v8::Array>()->Length(); + + Event exceptionEvent; + exceptionEvent.name = "error.execution"; + exceptionEvent.data.compound["exception"] = Data("'" + expr + "' does not evaluate to an array.", Data::VERBATIM);; + + _interpreter->receiveInternal(exceptionEvent); + throw(exceptionEvent); } void V8DataModel::eval(const std::string& expr) { @@ -280,6 +306,17 @@ std::string V8DataModel::evalAsString(const std::string& expr) { return std::string(*data); } +double V8DataModel::evalAsNumber(const std::string& expr) { + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.back()); + v8::Handle<v8::Value> result = evalAsValue(expr); + if (result->IsNumber()) { + return result->ToNumber()->NumberValue(); + } + return 0; +} + void V8DataModel::assign(const std::string& location, const Data& data) { v8::Locker locker; v8::HandleScope handleScope; @@ -308,49 +345,54 @@ v8::Handle<v8::Value> V8DataModel::evalAsValue(const std::string& expr) { if (script.IsEmpty() || result.IsEmpty()) { // throw an exception - assert(tryCatch.HasCaught()); - Event exceptionEvent; - exceptionEvent.name = "error.execution"; - - std::string exceptionString(*v8::String::AsciiValue(tryCatch.Exception())); - exceptionEvent.data.compound["exception"] = Data(exceptionString, Data::VERBATIM);; - - v8::Handle<v8::Message> message = tryCatch.Message(); - if (!message.IsEmpty()) { - std::string filename(*v8::String::AsciiValue(message->GetScriptResourceName())); - exceptionEvent.data.compound["filename"] = Data(filename, Data::VERBATIM); - - std::string sourceLine(*v8::String::AsciiValue(message->GetSourceLine())); - size_t startpos = sourceLine.find_first_not_of(" \t"); - if(std::string::npos != startpos) // removoe leading white space - sourceLine = sourceLine.substr(startpos); - - exceptionEvent.data.compound["sourceline"] = Data(sourceLine, Data::VERBATIM); - - std::stringstream ssLineNumber; - int lineNumber = message->GetLineNumber(); - ssLineNumber << lineNumber; - exceptionEvent.data.compound["linenumber"] = Data(ssLineNumber.str()); - - int startColumn = message->GetStartColumn(); - int endColumn = message->GetEndColumn(); - std::stringstream ssUnderline; - for (int i = 0; i < startColumn; i++) - ssUnderline << " "; - for (int i = startColumn; i < endColumn; i++) - ssUnderline << "^"; - exceptionEvent.data.compound["sourcemark"] = Data(ssUnderline.str(), Data::VERBATIM); - - std::string stackTrace(*v8::String::AsciiValue(tryCatch.StackTrace())); - exceptionEvent.data.compound["stacktrace"] = Data(stackTrace, Data::VERBATIM); + if (tryCatch.HasCaught()) + throwExceptionEvent(tryCatch); + } - } + return result; +} + +void V8DataModel::throwExceptionEvent(const v8::TryCatch& tryCatch) { + assert(tryCatch.HasCaught()); + Event exceptionEvent; + exceptionEvent.name = "error.execution"; + + std::string exceptionString(*v8::String::AsciiValue(tryCatch.Exception())); + exceptionEvent.data.compound["exception"] = Data(exceptionString, Data::VERBATIM);; + + v8::Handle<v8::Message> message = tryCatch.Message(); + if (!message.IsEmpty()) { + std::string filename(*v8::String::AsciiValue(message->GetScriptResourceName())); + exceptionEvent.data.compound["filename"] = Data(filename, Data::VERBATIM); + + std::string sourceLine(*v8::String::AsciiValue(message->GetSourceLine())); + size_t startpos = sourceLine.find_first_not_of(" \t"); + if(std::string::npos != startpos) // removoe leading white space + sourceLine = sourceLine.substr(startpos); + + exceptionEvent.data.compound["sourceline"] = Data(sourceLine, Data::VERBATIM); + + std::stringstream ssLineNumber; + int lineNumber = message->GetLineNumber(); + ssLineNumber << lineNumber; + exceptionEvent.data.compound["linenumber"] = Data(ssLineNumber.str()); + + int startColumn = message->GetStartColumn(); + int endColumn = message->GetEndColumn(); + std::stringstream ssUnderline; + for (int i = 0; i < startColumn; i++) + ssUnderline << " "; + for (int i = startColumn; i < endColumn; i++) + ssUnderline << "^"; + exceptionEvent.data.compound["sourcemark"] = Data(ssUnderline.str(), Data::VERBATIM); + + std::string stackTrace(*v8::String::AsciiValue(tryCatch.StackTrace())); + exceptionEvent.data.compound["stacktrace"] = Data(stackTrace, Data::VERBATIM); - _interpreter->receiveInternal(exceptionEvent); - throw(exceptionEvent); } - return result; + _interpreter->receiveInternal(exceptionEvent); + throw(exceptionEvent); } }
\ No newline at end of file diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h index 18e1ea4..6d4ca63 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h @@ -52,6 +52,7 @@ public: virtual std::string evalAsString(const std::string& expr); virtual bool evalAsBool(const std::string& expr); + virtual double evalAsNumber(const std::string& expr); static v8::Handle<v8::Value> jsIn(const v8::Arguments& args); static v8::Handle<v8::Value> jsPrint(const v8::Arguments& args); @@ -63,6 +64,7 @@ protected: v8::Handle<v8::Value> evalAsValue(const std::string& expr); virtual v8::Handle<v8::Value> getDataAsValue(const Data& data); + void throwExceptionEvent(const v8::TryCatch& tryCatch); }; diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8NodeList.h b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8NodeList.h index fb1b510..c454e65 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8NodeList.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8NodeList.h @@ -43,6 +43,7 @@ public: static v8::Handle<v8::Value> itemCallback(const v8::Arguments&); static v8::Handle<v8::Value> lengthAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info); + static v8::Handle<v8::Value> indexedPropertyCustomGetter(uint32_t, const v8::AccessorInfo&); static v8::Persistent<v8::FunctionTemplate> Tmpl; static v8::Handle<v8::FunctionTemplate> getTmpl() { @@ -60,6 +61,7 @@ public: instance->SetAccessor(v8::String::NewSymbol("length"), V8NodeList::lengthAttrGetter, 0, v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None)); + instance->SetIndexedPropertyHandler(V8NodeList::indexedPropertyCustomGetter, 0); prototype->Set(v8::String::NewSymbol("item"), v8::FunctionTemplate::New(V8NodeList::itemCallback, v8::Undefined()), static_cast<v8::PropertyAttribute>(v8::DontDelete)); diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8NodeListCustom.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8NodeListCustom.cpp new file mode 100644 index 0000000..c05c5a4 --- /dev/null +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8NodeListCustom.cpp @@ -0,0 +1,52 @@ +#include "V8NodeList.h" +#include "V8Element.h" +#include "V8Node.h" + +namespace Arabica { +namespace DOM { + +v8::Handle<v8::Value> V8NodeList::indexedPropertyCustomGetter(uint32_t index, const v8::AccessorInfo &info) { + v8::Local<v8::Object> self = info.Holder(); + V8NodeListPrivate* privData = V8DOM::toClassPtr<V8NodeListPrivate >(self->GetInternalField(0)); + + if (privData->nativeObj->getLength() >= index) { + switch(privData->nativeObj->item(index).getNodeType()) { + case Node_base::ELEMENT_NODE: { + Arabica::DOM::Element<std::string>* retVal = new Arabica::DOM::Element<std::string>(privData->nativeObj->item(index)); + + v8::Handle<v8::Function> retCtor = V8Element::getTmpl()->GetFunction(); + v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance()); + + struct V8Element::V8ElementPrivate* retPrivData = new V8Element::V8ElementPrivate(); + retPrivData->dom = privData->dom; + retPrivData->nativeObj = retVal; + + retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); + + retObj.MakeWeak(0, V8Element::jsDestructor); + return retObj; + } + default: { + Arabica::DOM::Node<std::string>* retVal = new Arabica::DOM::Node<std::string>(privData->nativeObj->item(index)); + + v8::Handle<v8::Function> retCtor = V8Node::getTmpl()->GetFunction(); + v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance()); + + struct V8Node::V8NodePrivate* retPrivData = new V8Node::V8NodePrivate(); + retPrivData->dom = privData->dom; + retPrivData->nativeObj = retVal; + + retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); + + retObj.MakeWeak(0, V8Node::jsDestructor); + return retObj; + } + } + } + + return v8::Undefined(); + +} + +} +}
\ No newline at end of file |