summaryrefslogtreecommitdiffstats
path: root/src/uscxml
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-28 20:59:38 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-28 20:59:38 (GMT)
commit3d3f434c5be68a7e2b86ecccbaba40887852db99 (patch)
treee9378262ad68305f5add6f27a4338c21033bc5e1 /src/uscxml
parent3b7be6b309e3a446e64f99511806c0ea7a440b8e (diff)
downloaduscxml-3d3f434c5be68a7e2b86ecccbaba40887852db99.zip
uscxml-3d3f434c5be68a7e2b86ecccbaba40887852db99.tar.gz
uscxml-3d3f434c5be68a7e2b86ecccbaba40887852db99.tar.bz2
More work on prolog datamodel
Diffstat (limited to 'src/uscxml')
-rw-r--r--src/uscxml/Message.cpp24
-rw-r--r--src/uscxml/Message.h4
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp96
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp18
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);