summaryrefslogtreecommitdiff
path: root/icespider/core/core.cpp
blob: 117c8690487ffc54006abebcaeba68428e61f506 (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
#include "core.h"
#include "exceptions.h"
#include <Ice/Initialize.h>
#include <Ice/ObjectAdapter.h>
#include <boost/filesystem/convenience.hpp>
#include <factory.impl.h>

INSTANTIATEFACTORY(IceSpider::Plugin, Ice::CommunicatorPtr, Ice::PropertiesPtr);

namespace IceSpider {
	const boost::filesystem::path Core::defaultConfig("config/ice.properties");

	Core::Core(const Ice::StringSeq & args)
	{
		Ice::InitializationData id;
		id.properties = Ice::createProperties();
		id.properties->parseCommandLineOptions("", args);
		auto config = id.properties->getPropertyWithDefault("IceSpider.Config", defaultConfig.string());
		if (boost::filesystem::exists(config)) {
			id.properties->load(config);
		}
		communicator = Ice::initialize(id);

		// Initialize routes
		for (const auto & rp : AdHoc::PluginManager::getDefault()->getAll<RouteHandlerFactory>()) {
			allRoutes.push_back(rp->implementation()->create(this));
		}
		std::sort(allRoutes.begin(), allRoutes.end(), [](const auto & a, const auto & b) {
			return a->path < b->path;
		});
		// Load plugins
		auto plugins = AdHoc::PluginManager::getDefault()->getAll<PluginFactory>();
		if (!plugins.empty()) {
			pluginAdapter = communicator->createObjectAdapterWithEndpoints("plugins", "default");
			for (const auto & pf : plugins) {
				auto p = pf->implementation()->create(communicator, communicator->getProperties());
				pluginAdapter->add(p, communicator->stringToIdentity(pf->name));
			}
			pluginAdapter->activate();
		}
	}

	Core::~Core()
	{
		// Unload plugins
		auto plugins = AdHoc::PluginManager::getDefault()->getAll<PluginFactory>();
		if (!plugins.empty()) {
			for (const auto & pf : plugins) {
				pluginAdapter->remove(communicator->stringToIdentity(pf->name));
			}
			pluginAdapter->deactivate();
			pluginAdapter->destroy();
		}
		// Terminate routes
		for (auto r : allRoutes) {
			delete r;
		}

		if (communicator) communicator->destroy();
	}

	void
	Core::process(IHttpRequest * request, const IRouteHandler * route) const
	{
		try {
			(route ? route : findRoute(request))->execute(request);
		}
		catch (const HttpException & he) {
			request->response(he.code, he.message);
		}
		catch (const std::exception & e) {
			request->response(500, e.what());
		}
		catch (...) {
			request->response(500, "Unknown internal server error");
		}
	}

	const IceSpider::IRouteHandler *
	Core::findRoute(const IceSpider::IHttpRequest *) const
	{
		throw Http404_NotFound();
	}

	Ice::ObjectPrx
	Core::getProxy(const char * type) const
	{
		char * buf = __cxxabiv1::__cxa_demangle(type, NULL, NULL, NULL);
		char * c = buf;
		int off = 0;
		while (*c) {
			if (*(c + 1) == ':' && *c == ':') {
				*c = '.';
				off += 1;
			}
			else if (off) {
				*c = *(c + off);
			}
			c += 1;
		}
		auto i = communicator->propertyToProxy(buf);
		free(buf);
		return i;
	}
}