summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/element/fetch/FetchElement.cpp
blob: da64bcf4b071c2a102d61e8af9cacc356048d933 (plain)
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) {

}

}