diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-04-12 11:57:08 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-04-12 11:57:08 (GMT) |
commit | ba050afaaad699e60ca657b311d5c34d038bb89c (patch) | |
tree | d4c79e30631c63e8557c6ec893a70dda46aa6cd5 /src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp | |
parent | 45ab2909e17f7e0348ccfe4179f23a897a2fd305 (diff) | |
download | uscxml-ba050afaaad699e60ca657b311d5c34d038bb89c.zip uscxml-ba050afaaad699e60ca657b311d5c34d038bb89c.tar.gz uscxml-ba050afaaad699e60ca657b311d5c34d038bb89c.tar.bz2 |
Refactoring for other datamodels
Diffstat (limited to 'src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp')
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp | 132 |
1 files changed, 110 insertions, 22 deletions
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index 2491fc4..22777fa 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -147,9 +147,13 @@ void V8DataModel::setEvent(const Event& event) { 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()); + // _event.data is a string or JSON + Data json = Data::fromJSON(event.content); + if (json) { + eventObj->Set(v8::String::New("data"), getDataAsValue(json)); + } else { + eventObj->Set(v8::String::New("data"), v8::String::New(Interpreter::spaceNormalize(event.content).c_str())); + } } else { // _event.data is KVP Event eventCopy(event); @@ -188,12 +192,23 @@ Data V8DataModel::getStringAsData(const std::string& content) { } Data V8DataModel::getValueAsData(const v8::Handle<v8::Value>& value) { + std::set<v8::Value*> foo = std::set<v8::Value*>(); + return getValueAsData(value, foo); +} + +Data V8DataModel::getValueAsData(const v8::Handle<v8::Value>& value, std::set<v8::Value*>& alreadySeen) { Data data; + + /// TODO: Breaking cycles does not work yet + if (alreadySeen.find(*value) != alreadySeen.end()) + return data; + alreadySeen.insert(*value); + if (false) { } else if (value->IsArray()) { v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); for (int i = 0; i < array->Length(); i++) { - data.array.push_back(getValueAsData(array->Get(i))); + data.array.push_back(getValueAsData(array->Get(i), alreadySeen)); } } else if (value->IsBoolean()) { data.atom = (value->ToBoolean()->Value() ? "true" : "false"); @@ -226,7 +241,7 @@ Data V8DataModel::getValueAsData(const v8::Handle<v8::Value>& value) { assert(properties->Get(i)->IsString()); v8::String::AsciiValue key(v8::Handle<v8::String>::Cast(properties->Get(i))); v8::Local<v8::Value> property = object->Get(properties->Get(i)); - data.compound[*key] = getValueAsData(property); + data.compound[*key] = getValueAsData(property, alreadySeen); } } else if (value->IsRegExp()) { LOG(ERROR) << "IsRegExp is unimplemented" << std::endl; @@ -374,9 +389,33 @@ std::string V8DataModel::evalAsString(const std::string& expr) { v8::Context::Scope contextScope(_contexts.back()); v8::Handle<v8::Value> result = evalAsValue(expr); if (result->IsObject()) { + v8::Local<v8::Object> obj = result->ToObject(); + v8::Local<v8::Object> proto; + + proto = obj->FindInstanceInPrototypeChain(Arabica::DOM::V8Document::getTmpl()); + if (!proto.IsEmpty()) { + struct Arabica::DOM::V8Document::V8DocumentPrivate* privData = + Arabica::DOM::V8DOM::toClassPtr<Arabica::DOM::V8Document::V8DocumentPrivate >(obj->GetInternalField(0)); + std::stringstream ss; + ss << privData->nativeObj->getDocumentElement(); + return ss.str(); + } + + proto = obj->FindInstanceInPrototypeChain(Arabica::DOM::V8Node::getTmpl()); + if (!proto.IsEmpty()) { + struct Arabica::DOM::V8Node::V8NodePrivate* privData = + Arabica::DOM::V8DOM::toClassPtr<Arabica::DOM::V8Node::V8NodePrivate >(obj->GetInternalField(0)); + std::stringstream ss; + ss << privData->nativeObj; + return ss.str(); + } + Data data = getValueAsData(result); return toStr(data); } + if (result->IsNumber()) { + return toStr(result->ToNumber()->NumberValue()); + } v8::String::AsciiValue data(result->ToString()); return std::string(*data); } @@ -392,40 +431,89 @@ double V8DataModel::evalAsNumber(const std::string& expr) { return 0; } -void V8DataModel::assign(const std::string& location, - const Arabica::DOM::Document<std::string>& doc, - const Arabica::DOM::Element<std::string>& dataElem) { +void V8DataModel::assign(const Arabica::DOM::Element<std::string>& assignElem, + const Arabica::DOM::Document<std::string>& doc, + const std::string& content) { v8::Locker locker; v8::HandleScope handleScope; v8::Context::Scope contextScope(_contexts.front()); v8::Handle<v8::Object> global = _contexts.front()->Global(); - global->Set(v8::String::New(location.c_str()), getDocumentAsValue(doc)); - + std::string key; + if (HAS_ATTR(assignElem, "id")) { + key = ATTR(assignElem, "id"); + } else if (HAS_ATTR(assignElem, "location")) { + key = ATTR(assignElem, "location"); + } + if (key.length() == 0) + throw Event("error.execution", Event::PLATFORM); + + if (HAS_ATTR(assignElem, "expr")) { + evalAsValue(key + " = " + ATTR(assignElem, "expr")); + } else if (doc) { + global->Set(v8::String::New(key.c_str()), getDocumentAsValue(doc)); + } else if (content.size() > 0) { + try { + evalAsValue(key + " = " + content); + } catch (...) { + evalAsValue(key + " = " + "\"" + Interpreter::spaceNormalize(content) + "\""); + } + } else { + global->Set(v8::String::New(key.c_str()), v8::Undefined()); + } } void V8DataModel::assign(const std::string& location, - const Data& data, - const Arabica::DOM::Element<std::string>& dataElem) { + const Data& data) { v8::Locker locker; v8::HandleScope handleScope; v8::Context::Scope contextScope(_contexts.front()); std::stringstream ssJSON; ssJSON << data; - assign(location, ssJSON.str(), dataElem); + evalAsValue(location + " = " + ssJSON.str()); } -void V8DataModel::assign(const std::string& location, - const std::string& expr, - const Arabica::DOM::Element<std::string>& dataElem) { - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.back()); - evalAsValue(location + " = " + expr); +void V8DataModel::init(const Arabica::DOM::Element<std::string>& dataElem, + const Arabica::DOM::Document<std::string>& doc, + const std::string& content) { + try { + assign(dataElem, doc, content); + } catch (Event e) { + // test 277 + std::string key; + if (HAS_ATTR(dataElem, "id")) { + key = ATTR(dataElem, "id"); + } else if (HAS_ATTR(dataElem, "location")) { + key = ATTR(dataElem, "location"); + } + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.front()); + + evalAsValue(key + " = undefined", true); + throw e; + } +}; + +void V8DataModel::init(const std::string& location, + const Data& data) { + try { + assign(location, data); + } catch (Event e) { + // test 277 + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.front()); + + evalAsValue(location + " = undefined", true); + throw e; + } + } -v8::Handle<v8::Value> V8DataModel::evalAsValue(const std::string& expr) { + +v8::Handle<v8::Value> V8DataModel::evalAsValue(const std::string& expr, bool dontThrow) { v8::TryCatch tryCatch; v8::Handle<v8::String> source = v8::String::New(expr.c_str()); v8::Handle<v8::Script> script = v8::Script::Compile(source); @@ -436,7 +524,7 @@ v8::Handle<v8::Value> V8DataModel::evalAsValue(const std::string& expr) { if (script.IsEmpty() || result.IsEmpty()) { // throw an exception - if (tryCatch.HasCaught()) + if (tryCatch.HasCaught() && !dontThrow) throwExceptionEvent(tryCatch); } |