diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-04-28 20:59:38 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-04-28 20:59:38 (GMT) |
commit | 3d3f434c5be68a7e2b86ecccbaba40887852db99 (patch) | |
tree | e9378262ad68305f5add6f27a4338c21033bc5e1 /src | |
parent | 3b7be6b309e3a446e64f99511806c0ea7a440b8e (diff) | |
download | uscxml-3d3f434c5be68a7e2b86ecccbaba40887852db99.zip uscxml-3d3f434c5be68a7e2b86ecccbaba40887852db99.tar.gz uscxml-3d3f434c5be68a7e2b86ecccbaba40887852db99.tar.bz2 |
More work on prolog datamodel
Diffstat (limited to 'src')
-rw-r--r-- | src/uscxml/Message.cpp | 24 | ||||
-rw-r--r-- | src/uscxml/Message.h | 4 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp | 96 | ||||
-rw-r--r-- | src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp | 18 |
4 files changed, 120 insertions, 22 deletions
diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp index 27e01e2..67198ea 100644 --- a/src/uscxml/Message.cpp +++ b/src/uscxml/Message.cpp @@ -308,6 +308,30 @@ Data Data::fromJSON(const std::string& jsonString) { return data; } +void Event::initContent(const std::string& content) { + // try to parse as JSON + Data json = Data::fromJSON(content); + if (json) { + data = json; + return; + } + + // try to parse as XML + Arabica::SAX2DOM::Parser<std::string> parser; + Arabica::SAX::CatchErrorHandler<std::string> errorHandler; + parser.setErrorHandler(errorHandler); + + std::istringstream is(content); + Arabica::SAX::InputSource<std::string> inputSource; + inputSource.setByteStream(is); + if (parser.parse(inputSource)) { + dom = parser.getDocument(); + return; + } + + this->content = content; +} + Event Event::fromXML(const std::string& xmlString) { Arabica::SAX2DOM::Parser<std::string> eventParser; Arabica::SAX::CatchErrorHandler<std::string> errorHandler; diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h index ea1e8ab..3bb30fc 100644 --- a/src/uscxml/Message.h +++ b/src/uscxml/Message.h @@ -173,10 +173,12 @@ public: Data getData() { return data; } - void setData(const Data& invokeId) { + void setData(const Data& data) { this->data = data; } + void initContent(const std::string& content); + static Event fromXML(const std::string& xmlString); Arabica::DOM::Document<std::string> toDocument(); std::string toXMLString() { diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp index 0c65fa9..7e63174 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp @@ -124,10 +124,10 @@ void SWIDataModel::setEvent(const Event& event) { PlCall("retractall(event(_))"); // simple values - PlCall("assert", PlCompound("event", PlCompound("name", PlString(event.name.c_str())))); + PlCall("assert", PlCompound("event", PlCompound("name", PlTerm(event.name.c_str())))); PlCall("assert", PlCompound("event", PlCompound("origin", PlString(event.origin.c_str())))); PlCall("assert", PlCompound("event", PlCompound("origintype", PlString(event.invokeid.c_str())))); - PlCall("assert", PlCompound("event", PlCompound("invokeid", PlString(event.origintype.c_str())))); + PlCall("assert", PlCompound("event", PlCompound("invokeid", PlTerm(event.origintype.c_str())))); PlCall("assert", PlCompound("event", PlCompound("raw", PlString(event.raw.c_str())))); // event.type @@ -143,11 +143,11 @@ void SWIDataModel::setEvent(const Event& event) { type = "external"; break; } - PlCall("assert", PlCompound("event", PlCompound("type", PlString(type.c_str())))); + PlCall("assert", PlCompound("event", PlCompound("type", PlTerm(type.c_str())))); // event.sendid if (!event.hideSendId) - PlCall("assert", PlCompound("event", PlCompound("sendid", PlString(event.sendid.c_str())))); + PlCall("assert", PlCompound("event", PlCompound("sendid", PlTerm(event.sendid.c_str())))); // event.data URL domUrl; @@ -170,9 +170,9 @@ void SWIDataModel::setEvent(const Event& event) { paramIter = event.params.upper_bound(paramIter->first); } if (uniqueKeys > 0) { - std::stringstream paramArray; paramIter = event.params.begin(); for(int i = 0; paramIter != event.params.end(); i++) { + std::stringstream paramArray; Event::params_t::const_iterator lastValueIter = event.params.upper_bound(paramIter->first); paramArray << paramIter->first << "(["; @@ -185,7 +185,8 @@ void SWIDataModel::setEvent(const Event& event) { } paramArray << "])"; std::stringstream paramExpr; - paramExpr << "assert(event(param(" << paramArray << ")))"; + paramExpr << "assert(event(param(" << paramArray.str() << ")))"; + //std::cout << paramExpr.str() << std::endl; PlCall(paramExpr.str().c_str()); paramIter = lastValueIter; @@ -208,15 +209,46 @@ bool SWIDataModel::validate(const std::string& location, const std::string& sche } uint32_t SWIDataModel::getLength(const std::string& expr) { -// std::cout << "SWIDataModel::getLength" << std::endl; - return 0; + PlCompound compound(expr.c_str()); + PlTermv termv(compound.arity()); + for (int i = 0; i < compound.arity(); i++) { + termv[i] = compound[i + 1]; + } + PlQuery query(compound.name(), termv); + uint32_t length = 0; + while(query.next_solution() > 0) + length++; + return length; } void SWIDataModel::setForeach(const std::string& item, const std::string& array, const std::string& index, uint32_t iteration) { - // std::cout << "SWIDataModel::setForeach" << std::endl; + PlCompound compound(array.c_str()); + PlCompound orig(array.c_str()); + PlTermv termv(compound.arity()); + for (int i = 0; i < compound.arity(); i++) { + termv[i] = compound[i + 1]; + } + { + int tmp = iteration + 1; + PlQuery query(compound.name(), termv); + while (tmp) { + query.next_solution(); + tmp--; + } + } + PlCall("retractall", PlCompound(index.c_str(), 1)); + PlCall("retractall", PlCompound(item.c_str(), 1)); + PlCall("assert", PlCompound(index.c_str(), PlTerm((long)iteration))); + + std::map<std::string, PlTerm> vars = resolveAtoms(compound, orig); + std::map<std::string, PlTerm>::iterator varIter = vars.begin(); + while(varIter != vars.end()) { + PlCall("assert", PlCompound(item.c_str(), varIter->second)); + varIter++; + } } void SWIDataModel::eval(const std::string& expr) { @@ -294,11 +326,45 @@ void SWIDataModel::assign(const Arabica::DOM::Element<std::string>& assignElem, const Arabica::DOM::Document<std::string>& doc, const std::string& content) { std::string expr = content; + std::string predicate; if (HAS_ATTR(assignElem, "expr")) { expr = ATTR(assignElem, "expr"); } - if (expr.length() > 0) + if (HAS_ATTR(assignElem, "id")) + predicate = ATTR(assignElem, "id"); + if (HAS_ATTR(assignElem, "location")) + predicate = ATTR(assignElem, "location"); + + if (predicate.size() > 0) { + size_t aritySep = predicate.find_first_of("/"); + if (aritySep != std::string::npos) { + std::string functor = predicate.substr(0, aritySep); + std::string arity = predicate.substr(aritySep + 1); + std::string callAssert = "assert"; + if (HAS_ATTR(assignElem, "type")) { + std::string type = ATTR(assignElem, "type"); + if (boost::iequals(type, "retract")) { + PlCall("retractall", PlCompound(functor.c_str(), strTo<long>(arity))); + } else if(boost::iequals(type, "append")) { + callAssert = "assertz"; + } else if(boost::iequals(type, "prepend")) { + callAssert = "asserta"; + } + } + // treat content as . seperated facts + std::stringstream factStream(content); + std::string item; + while(std::getline(factStream, item, '.')) { + std::string fact = boost::trim_copy(item); + if (fact.length() == 0) + continue; + PlCall((callAssert + "(" + functor + "(" + fact + "))").c_str()); + } + + } + } else if (expr.length() > 0) { eval(expr); + } } void SWIDataModel::assign(const std::string& location, const Data& data) { @@ -308,15 +374,11 @@ void SWIDataModel::assign(const std::string& location, const Data& data) { void SWIDataModel::init(const Arabica::DOM::Element<std::string>& dataElem, const Arabica::DOM::Document<std::string>& doc, const std::string& content) { - std::string key; - if (HAS_ATTR(dataElem, "id")) { - key = ATTR(dataElem, "id"); - } else if (HAS_ATTR(dataElem, "location")) { - key = ATTR(dataElem, "location"); - } assign(dataElem, doc, content); } -void SWIDataModel::init(const std::string& location, const Data& data) {} +void SWIDataModel::init(const std::string& location, const Data& data) { + assign(location, data); +} bool SWIDataModel::isDeclared(const std::string& expr) { return true; diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp index c8d86fa..6ddb83c 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp @@ -84,6 +84,8 @@ void BasicHTTPIOProcessor::httpRecvRequest(const HTTPServer::Request& req) { std::string value = evhttp_decode_uri(term.substr(split + 1).c_str()); if (boost::iequals(key, "_scxmleventname")) { reqEvent.name = value; + } else if (boost::iequals(key, "content")) { + reqEvent.initContent(value); } else { reqEvent.data.compound[key] = value; reqEvent.params.insert(std::make_pair(key, value)); @@ -187,11 +189,19 @@ void BasicHTTPIOProcessor::send(const SendRequest& req) { } // content - if (kvps.str().size() > 0) { - targetURL.setOutContent(kvps.str()); - } else if (req.content.size() > 0) { - targetURL.setOutContent(req.content); + + if (req.content.size() > 0) { + kvps << kvpSeperator << evhttp_encode_uri("content") << "=" << evhttp_encode_uri(req.content.c_str()); + kvpSeperator = "&"; + } + if (req.dom) { + std::stringstream xmlStream; + xmlStream << req.dom; + kvps << kvpSeperator << evhttp_encode_uri("content") << "=" << evhttp_encode_uri(xmlStream.str().c_str()); + kvpSeperator = "&"; } + targetURL.setOutContent(kvps.str()); + targetURL.setRequestType("post"); targetURL.addMonitor(this); |