summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/element
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-02-20 21:13:02 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-02-20 21:13:02 (GMT)
commita56f28b0db56ff3e39f0b50e4c55c52b7aeec696 (patch)
tree41cf67ea5cee9593e86272ab55367653fbd1c2f3 /src/uscxml/plugins/element
parent7c779099b3acd1fa969dde718299484ebe0d2775 (diff)
downloaduscxml-a56f28b0db56ff3e39f0b50e4c55c52b7aeec696.zip
uscxml-a56f28b0db56ff3e39f0b50e4c55c52b7aeec696.tar.gz
uscxml-a56f28b0db56ff3e39f0b50e4c55c52b7aeec696.tar.bz2
See detailled log
- Builds on windows again - All HTTP requests are no passed into interpreter - New response element to reply with data - Moved basichttp URL - New HTTP servlet invoker to register additional URLs - More bugfixes than I care to mention
Diffstat (limited to 'src/uscxml/plugins/element')
-rw-r--r--src/uscxml/plugins/element/fetch/FetchElement.cpp108
-rw-r--r--src/uscxml/plugins/element/fetch/FetchElement.h48
-rw-r--r--src/uscxml/plugins/element/response/ResponseElement.cpp68
-rw-r--r--src/uscxml/plugins/element/response/ResponseElement.h42
4 files changed, 266 insertions, 0 deletions
diff --git a/src/uscxml/plugins/element/fetch/FetchElement.cpp b/src/uscxml/plugins/element/fetch/FetchElement.cpp
new file mode 100644
index 0000000..33cb76e
--- /dev/null
+++ b/src/uscxml/plugins/element/fetch/FetchElement.cpp
@@ -0,0 +1,108 @@
+#include "FetchElement.h"
+#include <glog/logging.h>
+
+#include <event2/http.h>
+#include <event2/http_struct.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include <Pluma/Connector.hpp>
+#endif
+
+namespace uscxml {
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_CONNECTOR
+bool connect(pluma::Host& host) {
+ host.add( new FetchElementProvider() );
+ return true;
+}
+#endif
+
+boost::shared_ptr<ExecutableContentImpl> FetchElement::create(Interpreter* interpreter) {
+ boost::shared_ptr<FetchElement> invoker = boost::shared_ptr<FetchElement>(new FetchElement());
+ invoker->_interpreter = interpreter;
+ return invoker;
+}
+
+FetchElement::~FetchElement() {
+ URLFetcher::breakURL(_targetUrl);
+}
+
+void FetchElement::downloadCompleted(const URL& url) {
+ Event event;
+ event.name = _callback;
+
+ std::string content = url.getInContent();
+ std::map<std::string, std::string> headerFields = url.getInHeaderFields();
+
+ if (false) {
+ } else if (boost::iequals(_type, "text")) {
+ event.data.atom = content;
+ event.data.type = Data::VERBATIM;
+ } else if (boost::iequals(_type, "url")) {
+ } else if (boost::iequals(_type, "json")) {
+ event.data = Data::fromJSON(content);
+ } else if (boost::iequals(_type, "xml")) {
+ event = Event::fromXML(content);
+ }
+
+ _interpreter->receive(event);
+
+}
+
+void FetchElement::downloadFailed(const URL& url, int errorCode) {
+ Event event;
+ event.name = _callback + ".failed";
+
+ _interpreter->receive(event);
+
+}
+
+void FetchElement::enterElement(const Arabica::DOM::Node<std::string>& node) {
+ if (!HAS_ATTR(node, "target") && !HAS_ATTR(node, "targetexpr")) {
+ LOG(ERROR) << "Fetch element requires target or targetexpr";
+ return;
+ }
+ if (HAS_ATTR(node, "targetexpr") && !_interpreter->getDataModel()) {
+ LOG(ERROR) << "Fetch element with targetexpr requires datamodel";
+ return;
+ }
+ _target = (HAS_ATTR(node, "target") ? ATTR(node, "target") : _interpreter->getDataModel().evalAsString(ATTR(node, "targetexpr")));
+
+ if (!HAS_ATTR(node, "callback") && !HAS_ATTR(node, "callbackexpr")) {
+ LOG(ERROR) << "Fetch element requires callback or callbackexpr";
+ return;
+ }
+ if (HAS_ATTR(node, "callbackexpr") && !_interpreter->getDataModel()) {
+ LOG(ERROR) << "Fetch element with callbackexpr requires datamodel";
+ return;
+ }
+ _callback = (HAS_ATTR(node, "callback") ? ATTR(node, "callback") : _interpreter->getDataModel().evalAsString(ATTR(node, "callbackexpr")));
+
+ _type = (HAS_ATTR(node, "type") ? ATTR(node, "type") : "text");
+ if (!boost::iequals(_type, "text") &&
+ !boost::iequals(_type, "url") &&
+ !boost::iequals(_type, "json") &&
+ !boost::iequals(_type, "xml")) {
+ LOG(ERROR) << "Fetch element type attribute not one of text, url, json, xml.";
+ return;
+ }
+
+ _targetUrl = URL(_target);
+ if (!_targetUrl.isAbsolute()) {
+ if (!_interpreter->toAbsoluteURI(_targetUrl)) {
+ LOG(ERROR) << "Cannot transform " << _target << " into absolute URL";
+ return;
+ }
+ }
+
+ _targetUrl.addMonitor(this);
+ URLFetcher::fetchURL(_targetUrl);
+
+}
+
+void FetchElement::exitElement(const Arabica::DOM::Node<std::string>& node) {
+
+}
+
+} \ No newline at end of file
diff --git a/src/uscxml/plugins/element/fetch/FetchElement.h b/src/uscxml/plugins/element/fetch/FetchElement.h
new file mode 100644
index 0000000..0229048
--- /dev/null
+++ b/src/uscxml/plugins/element/fetch/FetchElement.h
@@ -0,0 +1,48 @@
+#ifndef FETCHELEMENT_H_R6GH94FV
+#define FETCHELEMENT_H_R6GH94FV
+
+#include <uscxml/Interpreter.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include "uscxml/plugins/Plugins.h"
+#endif
+
+namespace uscxml {
+
+class FetchElement : public ExecutableContentImpl, public URLMonitor {
+public:
+ FetchElement() {}
+ virtual ~FetchElement();
+ boost::shared_ptr<ExecutableContentImpl> create(Interpreter* interpreter);
+
+ std::string getLocalName() {
+ return "fetch";
+ }
+
+ std::string getNamespace() {
+ return "http://www.w3.org/2005/07/scxml";
+ }
+
+ bool processChildren() {
+ return false;
+ }
+
+ void enterElement(const Arabica::DOM::Node<std::string>& node);
+ void exitElement(const Arabica::DOM::Node<std::string>& node);
+ void downloadCompleted(const URL& url);
+ void downloadFailed(const URL& url, int errorCode);
+
+protected:
+ URL _targetUrl;
+ std::string _target;
+ std::string _callback;
+ std::string _type;
+};
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_INHERIT_PROVIDER(FetchElement, Element);
+#endif
+
+}
+
+#endif /* end of include guard: FETCHELEMENT_H_R6GH94FV */
diff --git a/src/uscxml/plugins/element/response/ResponseElement.cpp b/src/uscxml/plugins/element/response/ResponseElement.cpp
new file mode 100644
index 0000000..ce25036
--- /dev/null
+++ b/src/uscxml/plugins/element/response/ResponseElement.cpp
@@ -0,0 +1,68 @@
+#include "ResponseElement.h"
+#include "uscxml/plugins/invoker/http/HTTPServletInvoker.h"
+#include <glog/logging.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include <Pluma/Connector.hpp>
+#endif
+
+namespace uscxml {
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_CONNECTOR
+bool connect(pluma::Host& host) {
+ host.add( new ResponseElementProvider() );
+ return true;
+}
+#endif
+
+boost::shared_ptr<ExecutableContentImpl> ResponseElement::create(Interpreter* interpreter) {
+ boost::shared_ptr<ResponseElement> invoker = boost::shared_ptr<ResponseElement>(new ResponseElement());
+ invoker->_interpreter = interpreter;
+ return invoker;
+}
+
+void ResponseElement::enterElement(const Arabica::DOM::Node<std::string>& node) {
+ if (!HAS_ATTR(node, "request") && !HAS_ATTR(node, "requestexpr")) {
+ LOG(ERROR) << "Response element requires request or requestexpr";
+ return;
+ }
+ if (HAS_ATTR(node, "requestexpr") && !_interpreter->getDataModel()) {
+ LOG(ERROR) << "Response element with requestexpr requires datamodel";
+ return;
+ }
+ if (HAS_ATTR(node, "close")) {
+
+ }
+
+ std::string requestId = (HAS_ATTR(node, "request") ? ATTR(node, "request") : _interpreter->getDataModel().evalAsString(ATTR(node, "requestexpr")));
+
+ HTTPServletInvoker* servlet = _interpreter->getHTTPServlet();
+ tthread::lock_guard<tthread::recursive_mutex> lock(servlet->getMutex());
+
+ if (servlet->getRequests().find(requestId) == servlet->getRequests().end()) {
+ LOG(ERROR) << "No matching HTTP request for response element";
+ return;
+ }
+
+ std::string statusStr = (HAS_ATTR(node, "status") ? ATTR(node, "status") : "200");
+ if (!isNumeric(statusStr.c_str(), 10)) {
+ LOG(ERROR) << "Response element with non-numeric status " << statusStr;
+ return;
+ }
+ int status = strTo<int>(statusStr);
+
+ HTTPServer::Request httpReq = servlet->getRequests()[requestId];
+
+ HTTPServer::Reply httpReply(httpReq);
+ httpReply.status = status;
+
+ HTTPServer::reply(httpReply);
+ servlet->getRequests().erase(requestId);
+}
+
+void ResponseElement::exitElement(const Arabica::DOM::Node<std::string>& node) {
+
+}
+
+} \ No newline at end of file
diff --git a/src/uscxml/plugins/element/response/ResponseElement.h b/src/uscxml/plugins/element/response/ResponseElement.h
new file mode 100644
index 0000000..97ff9db
--- /dev/null
+++ b/src/uscxml/plugins/element/response/ResponseElement.h
@@ -0,0 +1,42 @@
+#ifndef RESPONSEELEMENT_H_I11KQ39Q
+#define RESPONSEELEMENT_H_I11KQ39Q
+
+#include <uscxml/Interpreter.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include "uscxml/plugins/Plugins.h"
+#endif
+
+namespace uscxml {
+
+class ResponseElement : public ExecutableContentImpl {
+public:
+ ResponseElement() {}
+ virtual ~ResponseElement() {}
+ boost::shared_ptr<ExecutableContentImpl> create(Interpreter* interpreter);
+
+ std::string getLocalName() {
+ return "response";
+ }
+
+ std::string getNamespace() {
+ return "http://www.w3.org/2005/07/scxml";
+ }
+
+ bool processChildren() {
+ return false;
+ }
+
+ void enterElement(const Arabica::DOM::Node<std::string>& node);
+ void exitElement(const Arabica::DOM::Node<std::string>& node);
+
+};
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_INHERIT_PROVIDER(ResponseElement, Element);
+#endif
+
+}
+
+
+#endif /* end of include guard: RESPONSEELEMENT_H_I11KQ39Q */