source: pacpusframework/branches/2.0-beta1/src/PacpusLib/ComponentManager.cpp@ 107

Last change on this file since 107 was 96, checked in by morasjul, 12 years ago

2.0 minor fixs

  • Property svn:executable set to *
File size: 12.5 KB
Line 
1// %pacpus:license{
2// This file is part of the PACPUS framework distributed under the
3// CECILL-C License, Version 1.0.
4// %pacpus:license}
5/// @version $Id: ComponentManager.cpp 76 2013-01-10 17:05:10Z kurdejma $
6
7#include <Pacpus/kernel/ComponentManager.h>
8#include <Pacpus/kernel/ComponentBase.h>
9#include <Pacpus/kernel/Log.h>
10#include <Pacpus/kernel/ConnectionBase.h>
11#include <QObject>
12
13#include <QDomNodeList>
14
15using namespace pacpus;
16
17DECLARE_STATIC_LOGGER("pacpus.core.ComponentManager");
18
19ComponentManager * ComponentManager::mInstance = NULL;
20
21ComponentManager * ComponentManager::create()
22{
23 return getInstance();
24}
25
26ComponentManager * ComponentManager::getInstance()
27{
28 LOG_TRACE("getInstance()");
29 LOG_TRACE("before: mInstance = " << mInstance);
30
31 if (!mInstance)
32 {
33 LOG_INFO("creating new instance...");
34 mInstance = new ComponentManager();
35 LOG_DEBUG("mInstance = " << mInstance);
36 }
37
38 LOG_TRACE("after: mInstance = " << mInstance);
39 return mInstance;
40}
41
42void ComponentManager::destroy()
43{
44 LOG_TRACE("destroy");
45
46 delete mInstance;
47 mInstance = NULL;
48}
49
50ComponentManager::ComponentManager()
51{
52 LOG_TRACE("constructor");
53
54 xmlTree_ = XmlConfigFile::create();
55 LOG_DEBUG("component manager was created");
56}
57
58ComponentManager::~ComponentManager()
59{
60 LOG_TRACE("destructor");
61
62 QMutableMapIterator<ComponentMap::key_type, ComponentMap::mapped_type> it(componentMap_);
63 while (it.hasNext())
64 unRegisterComponent(it.next().key());
65
66 LOG_DEBUG("component manager was deleted");
67}
68
69bool ComponentManager::registerComponentFactory(ComponentFactoryBase* addr, const QString& type)
70{
71 LOG_TRACE("registerComponentFactory(type="<< type << ")");
72
73 if (factoryMap_.contains(type))
74 {
75 LOG_WARN("cannot register a component factory of type '" << type << "'. It already belongs to the manager");
76 return false;
77 }
78
79 factoryMap_[type] = addr;
80 LOG_INFO("registered component factory '" << type << "'");
81
82 return true;
83}
84
85bool ComponentManager::unRegisterComponentFactory(const QString& type)
86{
87 LOG_TRACE("unRegisterComponentFactory(type="<< type << ")");
88
89 if (!factoryMap_.contains(type))
90 {
91 LOG_WARN("cannot unregister component factory '" << type << "'. It was not registered");
92 return false;
93 }
94
95 factoryMap_.remove(type);
96 LOG_INFO("unregistered component factory '" << type << "'");
97
98 return true;
99}
100
101bool ComponentManager::registerComponent(ComponentBase* addr, const QString& name)
102{
103 LOG_TRACE("registerComponent(name="<< name << ")");
104
105 if (componentMap_.contains(name))
106 {
107 LOG_WARN("cannot register component '" << name << "'. A component with the same name exists already");
108 return false;
109 }
110
111 componentMap_[name] = addr;
112 LOG_INFO("registered component " << name);
113
114 return true;
115}
116
117bool ComponentManager::unRegisterComponent(const QString& name)
118{
119 LOG_TRACE("unRegisterComponent(name="<< name << ")");
120
121 if (!componentMap_.contains(name))
122 {
123 LOG_WARN("cannot unregister component '" << name << "'. It was not registered");
124 return false;
125 }
126
127 // FIXME: delete component
128 //delete componentMap_[name];
129 componentMap_.remove(name);
130 LOG_INFO("unregistered component '" << name << "'");
131
132 return true;
133}
134
135bool ComponentManager::createComponent(const QString& type, const QString& name)
136{
137 LOG_TRACE("createComponent(type=" << type << ", " << "name="<< name << ")");
138
139 FactoryMap::iterator it = factoryMap_.find(type);
140 if (it != factoryMap_.end())
141 {
142 (*it)->addComponent(name);
143 return true;
144 }
145
146 LOG_WARN("cannot create component '" << name << "'"
147 << ". Component factory for type '" << type << "'"
148 << " does not exist or was not registered"
149 );
150 return false;
151}
152
153bool ComponentManager::loadPlugin(const QString& filename)
154{
155 LOG_TRACE("loadPlugin(filename=" << filename << ")");
156
157 pluginLoader_.setFileName(filename);
158
159 if (!pluginLoader_.load()) {
160 LOG_ERROR("cannot load plugin '" << filename << "'"
161 << ". Plugin loader returned error: " << pluginLoader_.errorString()
162 );
163 return false;
164 }
165
166 QObject * plugin = pluginLoader_.instance();
167 if (NULL == plugin) {
168 LOG_WARN("cannot create an instance of the plugin '" << filename << "'"
169 << ". Plugin loader returned error: " << pluginLoader_.errorString()
170 );
171 return false;
172 }
173 pluginList_.append(plugin);
174 LOG_INFO("loaded plugin '" << qobject_cast<PacpusPluginInterface*>(plugin)->name() << "'"
175 << " from file '" << pluginLoader_.fileName() << "'"
176 );
177 return true;
178}
179
180bool ComponentManager::createConnection(const QString& outputSignature, const QString& inputSignature, const QString& type, int priority = 0)
181{
182 QStringList output = outputSignature.split(".");
183 QStringList input = inputSignature.split(".");
184
185 if(getComponent(output[0])==NULL) {
186 LOG_WARN("cannot make connection : component " << output[0] << " not found");
187 return false;}
188 if(getComponent(output[0])->getOutput(output[1]) == NULL) {
189 LOG_WARN("cannot make connection : component " << output[0] << " doesn't have output " << output[1]);
190 return false;}
191 if(getComponent(input[0])==NULL) {
192 LOG_WARN("cannot make connection : component " << input[0] << " not found");
193 return false;}
194 if(getComponent(input[0])->getInput(input[1]) == NULL) {
195 LOG_WARN("cannot make connection : component " << input[0] << " doesn't have intput " << input[1]);
196 return false;}
197
198 // NOTE Create communicationInterface if needed ??
199
200 return connectInterface(getComponent(output[0])->getOutput(output[1]), getComponent(input[0])->getInput(input[1]), priority);
201
202}
203
204std::size_t ComponentManager::loadComponents(const QString& configFilename)
205{
206 LOG_TRACE("loadComponents(filename=" << configFilename << ")");
207
208 // load the components tree in memory
209 xmlTree_->loadFile(configFilename);
210
211 {
212 // Load the plugins containing the components
213 QStringList plugins = xmlTree_->getAllPlugins();
214 Q_FOREACH (QString plugin, plugins) {
215 if (!loadPlugin(plugin)) {
216 LOG_WARN("cannot load plugin '" << plugin << "'");
217 }
218 }
219 }
220
221 QDomNodeList componentsNodeList = xmlTree_->getAllComponents();
222 XmlComponentConfig cfg;
223
224 // First, create all the components in the XML list
225 for (int i = 0; i < componentsNodeList.size(); ++i) {
226 cfg.localCopy(componentsNodeList.item(i).toElement());
227 QString componentType = cfg.getComponentType();
228 QString componentName = cfg.getComponentName();
229 //LOG_DEBUG("try to create component '" << componentName << "'");
230 // create the component and automatically add it to the component manager list
231 if (!createComponent(componentType, componentName)) {
232 LOG_ERROR("cannot create component '" << componentName << "'");
233 continue;
234 }
235 }
236
237 int componentsToConfigureCount = componentMap_.count();
238
239 // Second, try to configure the components without regarding the dependencies
240 for (int i = 0; i < componentsNodeList.size(); ++i) {
241 //LOG_DEBUG("try to configure component '" << (*it) << "'");
242 cfg.localCopy(componentsNodeList.item(i).toElement());
243 QString componentName = cfg.getComponentName();
244
245 // copy locally the config parameters of the component
246 ComponentBase * component = getComponent(componentName);
247 if (NULL == component) {
248 LOG_WARN("component '" << componentName << "' does not exist");
249 } else {
250 component->param.localCopy(cfg.qDomElement());
251 component->configuration_ = component->configureComponent(cfg);
252
253 }
254 } // for
255
256 // Third, if some components requested a delayed configuration, retry
257 for (int i = 0; i < componentsNodeList.size(); ++i) {
258 cfg.localCopy(componentsNodeList.item(i).toElement());
259 QString componentName = cfg.getComponentName();
260
261 ComponentBase * component = getComponent(componentName);
262 if (NULL == component) {
263 LOG_WARN("component '" << componentName << "' does not exist");
264 } else {
265 if (component->configuration_ == ComponentBase::CONFIGURATION_DELAYED) {
266 //LOG_DEBUG("try to configure component '" << (*it) << "'");
267
268 // copy locally the config parameters of the component
269 component->param.localCopy(cfg.qDomElement());
270 component->configuration_ = component->configureComponent(cfg);
271 }
272
273 if (component->configuration_ == ComponentBase::CONFIGURED_OK) {
274 --componentsToConfigureCount;
275 } else {
276 /*LOG_ERROR("cannot configure component '" << (*it) << "'"
277 << ". Dependencies with other components are too complex"
278 << ". It was not configured, please review your configuration and/or your component"
279 );*/
280 component->configuration_ = ComponentBase::CONFIGURED_FAILED;
281 }
282 }
283 } // for
284
285 LOG_INFO(componentMap_.count() << " component(s) were loaded");
286 if (componentsToConfigureCount > 0) {
287 LOG_WARN(componentsToConfigureCount << " component(s) were not configured");
288 }
289
290 // Fourthly, create connections find in the XML list
291 QDomNodeList connectionsNodeList = xmlTree_->getAllConnections();
292
293 for (int i = 0; i < connectionsNodeList.size(); ++i) {
294
295 cfg.localCopy(connectionsNodeList.item(i).toElement());
296 QString connectionInput = cfg.getConnectionInput();
297 QString connectionOutput = cfg.getConnectionOutput();
298 QString connectionType = cfg.getConnectionType();
299 int connectionPriority = cfg.getConnectionPriority();
300
301 if (!createConnection(connectionOutput, connectionInput, connectionType,connectionPriority)) {
302 LOG_ERROR("cannot create connection '" << connectionOutput+"=>"+connectionInput << "'");
303 continue;
304 }
305 }
306
307 return componentMap_.count();
308}
309
310bool ComponentManager::start()
311{
312 LOG_TRACE("start()");
313
314 bool result = true;
315 for (ComponentMap::iterator it = componentMap_.begin(), itend = componentMap_.end(); it != itend; ++it )
316 result &= start(it.key());
317
318 return result;
319}
320
321bool ComponentManager::start(const QString& componentName)
322{
323 LOG_TRACE("start(component=" << componentName << ")");
324
325 ComponentBase* component = getComponent(componentName);
326 if (!component)
327 {
328 LOG_WARN("cannot start component '" << componentName << "'. It does not exist!");
329 return false;
330 }
331
332 LOG_INFO("starting component '" << componentName << "'...");
333 if (!component->startComponent())
334 LOG_WARN("cannot start component '" << componentName << "'. It can already be started");
335
336 return true;
337}
338
339bool ComponentManager::stop()
340{
341 LOG_TRACE("stop()");
342
343 bool result = true;
344 for (ComponentMap::iterator it = componentMap_.begin(); it != componentMap_.end(); ++it)
345 result &= stop(it.key());
346
347 return result;
348}
349
350bool ComponentManager::stop(const QString& componentName)
351{
352 LOG_TRACE("stop(component=" << componentName << ")");
353
354 ComponentBase* component = getComponent(componentName);
355 if (!component)
356 {
357 LOG_WARN("cannot stop component '" << componentName << "'" << ". It does not exist");
358 return false;
359 }
360
361 LOG_INFO("stopping component '" << componentName << "'...");
362 if (!component->stopComponent())
363 LOG_WARN("cannot stop component '" << componentName << "'" << ". It can be already stopped");
364
365 return true;
366}
367
368ComponentBase* ComponentManager::getComponent(const QString& name)
369{
370 LOG_TRACE("getComponent(name=" << name << ")");
371
372 ComponentMap::iterator it = componentMap_.find(name);
373 if (it != componentMap_.end())
374 return *it;
375
376 LOG_WARN("cannot retrieve component '" << name << "'" << ". It does not exist");
377 return NULL;
378}
379
380QStringList ComponentManager::getAllComponentsName() const
381{
382 LOG_TRACE("getAllComponentsName()");
383 return xmlTree_->getAllComponentsNames();
384}
Note: See TracBrowser for help on using the repository browser.