summaryrefslogtreecommitdiff
path: root/project2/console/consoleAppEngine.cpp
blob: 592b006c4fbedd5bd6d577474e60dfd2f6e1637e (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <pch.hpp>
#include <glibmm/exception.h>
#include <cxxabi.h>
#include "consoleAppEngine.h"
#include "consolePresenter.h"
#include "safeMapFind.h"
#include "logger.h"
#include "viewHost.h"
#include "taskHost.h"
#include "scriptLoader.h"
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <iostream>

StaticMessageException(InvalidScriptName, "Script name should be group/name");
SimpleMessageException(UnknownPlatformAlias);

class ShowHelpTrigger : public Options::Target {
	public:
		void reset() const { }
		bool paramRequired() const {
			return false;
		}
		void consume(const Glib::ustring &, const VariableType &, const Options::CurrentPlatform &) const {
			fprintf(stdout, "Help\n");
			Plugable::onAll<Options>(boost::bind(&ShowHelpTrigger::outputOptions, this, _1));
			exit(1);
		}
	private:
		void outputOptions(const Options * options) const {
			fprintf(stdout, "  * %s\n", options->name.c_str());
			BOOST_FOREACH(const auto & option, options->allOptions()) {
				fprintf(stdout, "    * %s - %s\n", option->name().c_str(), option->description().c_str());
			}
		}
};

DECLARE_OPTIONS(ConsoleApplicationEngine, "Console options")
("help", new ShowHelpTrigger(),
 "Print usage and exit")("h")
("console.platform", Options::value(&reqPlatform),
 "Platform")("p")
("console.queryParam", Options::functions(
		[](const VariableType & v) {
			Glib::ustring vs(v.as<Glib::ustring>());
			parameters.insert(Parameters::value_type(vs.substr(0, vs.find('=')), vs.substr(vs.find('=') + 1)));
		},
		boost::bind(&Parameters::clear, &parameters)),
 "Query parameter")("q")
END_OPTIONS(ConsoleApplicationEngine);

ConsoleApplicationEngine::ToDoList ConsoleApplicationEngine::todolist;
ConsoleApplicationEngine::Parameters ConsoleApplicationEngine::parameters;
Glib::ustring ConsoleApplicationEngine::reqPlatform;

ConsoleApplicationEngine::ConsoleApplicationEngine() :
	runtime(new Session(boost::uuids::random_generator()())),
	presenter(new ConsolePresenter())
{
}

ConsoleApplicationEngine::~ConsoleApplicationEngine()
{
}

class ScriptRunner : public TaskHost, public ViewHost {
	public:
		ScriptRunner(ScriptReaderPtr script, MultiRowSetPresenterPtr p) :
			SourceObject(script->root()),
			CommonObjects(script->root()),
			CheckHost(script->root()),
			TaskHost(script->root()),
			ViewHost(script->root()),
			presenter(p)
		{
		}

		MultiRowSetPresenterPtr getPresenter(ExecContext *) const
		{
			return presenter;
		}

		void process(ExecContext * ec)
		{
			runChecks(ec);
			execute(ec);
			executeViews(ec);
		}
	private:
		MultiRowSetPresenterPtr presenter;
};

void
ConsoleApplicationEngine::process(ScriptReaderPtr s)
{
	try {
		boost::intrusive_ptr<ScriptRunner> sr = new ScriptRunner(s, presenter);
		sr->process(this);
	}
	catch (const std::exception & e) {
		char * buf = __cxxabiv1::__cxa_demangle(typeid(e).name(), NULL, NULL, NULL);
		Logger()->messagef(LOG_ERR, "%s: Script errored: %s: %s", __FUNCTION__, buf, e.what());
		free(buf);
	}
	catch (const Glib::Exception & e) {
		char * buf = __cxxabiv1::__cxa_demangle(typeid(e).name(), NULL, NULL, NULL);
		Logger()->messagebf(LOG_ERR, "%s: Script errored: %s: %s", __FUNCTION__, buf, e.what());
		free(buf);
	}
}

SessionPtr
ConsoleApplicationEngine::getSession() const
{
	return runtime;
}

VariableType
ConsoleApplicationEngine::getParameter(const VariableType & key) const
{
	return safeMapLookup<ParamNotFound>(parameters, key);
}

void
ConsoleApplicationEngine::process()
{
	BOOST_FOREACH(const auto & todo, todolist) {
		Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1));
		Logger()->messagebf(LOG_DEBUG, "%s: Beginning script '%s/%s'", __FUNCTION__, todo.get<0>(), todo.get<1>());

		Logger()->messagef(LOG_DEBUG, "%s: Processing file", __FUNCTION__);
		process(ScriptReader::resolveScript(todo.get<0>(), todo.get<1>(), false));
		Logger()->messagef(LOG_DEBUG, "%s: Complete", __FUNCTION__);

		Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1));
	}
}

void
ConsoleApplicationEngine::appendScript(const char * arg)
{
	const char * sl = strchr(arg, '/');
	if (sl) {
		todolist.push_back(ConsoleApplicationEngine::ToDo(std::string(arg, sl), sl + 1));
		sl++;
	}
	else {
		throw InvalidScriptName();
	}
}