1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/**
* @file
* @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de)
* @copyright Simplified BSD
*
* @cond
* This program is free software: you can redistribute it and/or modify
* it under the terms of the FreeBSD license as published by the FreeBSD
* project.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the FreeBSD license along with this
* program. If not, see <http://www.opensource.org/licenses/bsd-license>.
* @endcond
*/
#include <boost/algorithm/string.hpp>
#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 pluginConnect(pluma::Host& host) {
host.add( new FetchElementProvider() );
return true;
}
#endif
boost::shared_ptr<ExecutableContentImpl> FetchElement::create(InterpreterImpl* interpreter) {
boost::shared_ptr<FetchElement> element = boost::shared_ptr<FetchElement>(new FetchElement());
element->_interpreter = interpreter;
return element;
}
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 (!_targetUrl.toAbsolute(_interpreter->getBaseURI())) {
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) {
}
}
|