source: pacpusframework/branches/0.0.x/src/PacpusLib/ComponentManager.cpp@ 305

Last change on this file since 305 was 116, checked in by Marek Kurdej, 11 years ago

Added: PacpusException - base class for all exceptions. DbiteExceptions inherits from it.
Added: PacpusLibConfig.h - dllimport/dllexport clauses separated from pacpus.h.
Update: comments.

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