Merge branch 'master' of https://github.com/otcshare/automotive-message-broker
[profile/ivi/automotive-message-broker.git] / ambd / pluginloader.cpp
1 /*
2 Copyright (C) 2012 Intel Corporation
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19
20 #include "pluginloader.h"
21 #include "glibmainloop.h"
22
23 #include <iostream>
24 #include <stdexcept>
25 #include <json-glib/json-glib.h>
26
27
28 using namespace std;
29
30 /********************************************
31  * Example JSON config:
32  * {
33  *      sources: [ path1, path2, path3 ]
34  *      sinks: [ path1, path2, path3 ]
35  * }
36  * 
37 **********************************************/
38
39 PluginLoader::PluginLoader(string configFile, AbstractRoutingEngine* re, int argc, char** argv): f_create(NULL), routingEngine(re), mMainLoop(nullptr)
40 {
41         DebugOut()<<"Loading config file: "<<configFile<<endl;
42         
43         JsonParser* parser = json_parser_new();
44         GError* error = nullptr;
45         if(!json_parser_load_from_file(parser, configFile.c_str(), &error))
46         {
47                 DebugOut()<<"Failed to load config: "<<error->message;
48                 throw std::runtime_error("Failed to load config");
49         }
50         
51         JsonNode* node = json_parser_get_root(parser);
52         
53         if(node == nullptr)
54                 throw std::runtime_error("Unable to get JSON root object");
55         
56         JsonReader* reader = json_reader_new(node);
57         
58         if(reader == nullptr)
59                 throw std::runtime_error("Unable to create JSON reader");
60         
61         DebugOut()<<"Config members: "<<json_reader_count_members(reader)<<endl;
62
63         if(json_reader_read_member(reader,"mainloop"))
64         {
65                 /// there is a mainloop entry.  Load the plugin:
66
67                 string mainloopstr = json_reader_get_string_value(reader);
68
69                 mMainLoop = loadMainLoop(mainloopstr,argc, argv);
70
71                 if(!mMainLoop)
72                 {
73                         DebugOut(0)<<"Failed to load main loop plugin."<<endl;
74                 }
75         }
76         else if(!mMainLoop)
77         {
78                 /// there is no mainloop entry, use default glib
79                 DebugOut()<<"No mainloop specified in config.  Using glib by default."<<endl;
80                 mMainLoop = new GlibMainLoop(argc,argv);
81         }
82         
83         json_reader_end_member(reader);
84
85         if(!json_reader_read_member(reader,"sources"))
86         {
87
88                 const GError * srcReadError = json_reader_get_error(reader);
89
90                 DebugOut()<<"Error getting sources member: "<<srcReadError->message<<endl;
91                 throw std::runtime_error("Error getting sources member");
92         }
93         
94         g_assert(json_reader_is_array(reader));
95         
96         
97         for(int i=0; i < json_reader_count_elements(reader); i++)
98         {
99                 json_reader_read_element(reader,i);
100                 
101                 gchar** srcMembers = json_reader_list_members(reader);
102
103                 std::map<std::string, std::string> configurationMap;
104
105                 for(int i=0; i< json_reader_count_members(reader); i++)
106                 {
107                         json_reader_read_member(reader,srcMembers[i]);
108                         configurationMap[srcMembers[i]] = json_reader_get_string_value(reader);
109                         DebugOut()<<"plugin config key: "<<srcMembers[i]<<" value: "<<configurationMap[srcMembers[i]]<<endl;
110                         json_reader_end_member(reader);
111                 }
112
113                 json_reader_read_member(reader, "path");
114                 string path = json_reader_get_string_value(reader);
115                 json_reader_end_member(reader);
116
117                 AbstractSource* plugin = loadPlugin<AbstractSource*>(path,configurationMap);
118                 
119                 if(plugin != nullptr)
120                 {
121                         mSources.push_back(plugin);
122                 }
123
124                 json_reader_end_element(reader);
125         }
126                         
127         json_reader_end_member(reader);
128
129         ///read the sinks:
130                 
131         json_reader_read_member(reader,"sinks");
132
133         for(int i=0; i < json_reader_count_elements(reader); i++)
134         {
135                 json_reader_read_element(reader,i);
136
137                 gchar** srcMembers = json_reader_list_members(reader);
138
139                 std::map<std::string, std::string> configurationMap;
140
141                 for(int i=0; i< json_reader_count_members(reader); i++)
142                 {
143                         json_reader_read_member(reader,srcMembers[i]);
144                         configurationMap[srcMembers[i]] = json_reader_get_string_value(reader);
145                         json_reader_end_member(reader);
146                 }
147
148                 json_reader_read_member(reader, "path");
149                 string path = json_reader_get_string_value(reader);
150                 json_reader_end_member(reader);
151
152                 AbstractSinkManager* plugin = loadPlugin<AbstractSinkManager*>(path, configurationMap);
153
154                 if(plugin == nullptr)
155                 {
156                         throw std::runtime_error("plugin is not a SinkManager");
157                 }
158
159                 json_reader_end_element(reader);
160         }
161
162         json_reader_end_member(reader);
163         
164         ///TODO: this will probably explode:
165         
166         if(error) g_error_free(error);
167         
168         g_object_unref(reader);
169         g_object_unref(parser);
170         
171 }
172
173 PluginLoader::~PluginLoader()
174 {
175         for(auto itr = mSinks.begin(); itr != mSinks.end(); itr++)
176         {
177                 delete *itr;
178         }
179
180         for(auto itr = mSources.begin(); itr != mSources.end(); itr++)
181         {
182                 delete *itr;
183         }
184 }
185
186 SinkList PluginLoader::sinks()
187 {
188         return mSinks;
189 }
190
191 IMainLoop *PluginLoader::mainloop()
192 {
193         return mMainLoop;
194 }
195
196 SourceList PluginLoader::sources()
197 {
198         return mSources;
199 }
200
201
202
203 std::string PluginLoader::errorString()
204 {
205         return mErrorString;
206 }
207