source: pacpusframework/trunk/src/PacpusLib/ComponentManager.cpp@ 47

Last change on this file since 47 was 47, checked in by sgosseli, 11 years ago

Minor: cleanup, coding style, remove useless search in a map.

File size: 10.4 KB
Line 
1/**
2 *
3 * Distributed under the UTC Heudiascy Pacpus License, Version 1.0.
4 * Copyright (c) UTC Heudiasyc 2010 - 2013. All rights reserved.
5 *
6 * See the LICENSE file for more information or a copy at:
7 * http://www.hds.utc.fr/~kurdejma/LICENSE_1_0.txt
8 *
9 */
10
11#include <Pacpus/kernel/ComponentManager.h>
12#include <Pacpus/kernel/ComponentBase.h>
13#include <Pacpus/kernel/Log.h>
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
180std::size_t ComponentManager::loadComponents(const QString& configFilename)
181{
182 LOG_TRACE("loadComponents(filename=" << configFilename << ")");
183
184 // load the components tree in memory
185 xmlTree_->loadFile(configFilename);
186
187 {
188 // Load the plugins containing the components
189 QStringList plugins = xmlTree_->getAllPlugins();
190 Q_FOREACH (QString plugin, plugins) {
191 if (!loadPlugin(plugin)) {
192 LOG_WARN("cannot load plugin '" << plugin << "'");
193 }
194 }
195 }
196
197 QStringList componentsNameList = xmlTree_->getAllComponents();
198 LOG_DEBUG("components in the config file: '" << componentsNameList.join("|") << "'");
199
200 XmlComponentConfig cfg;
201
202 // First, create all the components in the XML list
203 for (QStringList::iterator it = componentsNameList.begin(); it != componentsNameList.end(); ++it) {
204 LOG_DEBUG("try to create component '" << (*it) << "'");
205 cfg.localCopy(xmlTree_->getComponent(*it));
206 QString componentType = cfg.getComponentType();
207 QString componentName = cfg.getComponentName();
208 // create the component and automatically add it to the component manager list
209 if (!createComponent(componentType, componentName)) {
210 LOG_ERROR("cannot create component '" << componentName << "'");
211 continue;
212 }
213 }
214
215 int componentsToConfigureCount = componentMap_.count();
216
217 // Second, try to configure the components without regarding the dependencies
218 for (QStringList::iterator it = componentsNameList.begin(); it != componentsNameList.end(); ++it) {
219 LOG_DEBUG("try to configure component '" << (*it) << "'");
220 cfg.localCopy(xmlTree_->getComponent(*it));
221 QString componentName = cfg.getComponentName();
222
223 // copy locally the config parameters of the component
224 ComponentBase * component = getComponent(componentName);
225 if (NULL == component) {
226 LOG_WARN("component '" << componentName << "' does not exist");
227 } else {
228 component->param.localCopy(cfg.qDomElement());
229 component->configuration_ = component->configureComponent(cfg);
230
231 }
232 } // for
233
234 // Third, if some components requested a delayed configuration, retry
235 for (QStringList::iterator it = componentsNameList.begin(); it != componentsNameList.end() ; ++it) {
236 cfg.localCopy(xmlTree_->getComponent(*it));
237 QString componentName = cfg.getComponentName();
238
239 ComponentBase * component = getComponent(componentName);
240 if (NULL == component) {
241 LOG_WARN("component '" << componentName << "' does not exist");
242 } else {
243 if (component->configuration_ == ComponentBase::CONFIGURATION_DELAYED) {
244 LOG_DEBUG("try to configure component '" << (*it) << "'");
245
246 // copy locally the config parameters of the component
247 component->param.localCopy(cfg.qDomElement());
248 component->configuration_ = component->configureComponent(cfg);
249 }
250
251 if (component->configuration_ == ComponentBase::CONFIGURED_OK) {
252 --componentsToConfigureCount;
253 } else {
254 LOG_ERROR("cannot configure component '" << (*it) << "'"
255 << ". Dependencies with other components are too complex"
256 << ". It was not configured, please review your configuration and/or your component"
257 );
258 component->configuration_ = ComponentBase::CONFIGURED_FAILED;
259 }
260 }
261 } // for
262
263 LOG_INFO(componentMap_.count() << " component(s) were loaded");
264 if (componentsToConfigureCount > 0) {
265 LOG_WARN(componentsToConfigureCount << " component(s) were not configured");
266 }
267
268 return componentMap_.count();
269}
270
271bool ComponentManager::start()
272{
273 LOG_TRACE("start()");
274
275 bool result = true;
276 for (ComponentMap::iterator it = componentMap_.begin(), itend = componentMap_.end(); it != itend; ++it )
277 result &= start(it.key());
278
279 return result;
280}
281
282bool ComponentManager::start(const QString& componentName)
283{
284 LOG_TRACE("start(component=" << componentName << ")");
285
286 ComponentBase* component = getComponent(componentName);
287 if (!component)
288 {
289 LOG_WARN("cannot start component '" << componentName << "'. It does not exist!");
290 return false;
291 }
292
293 LOG_INFO("starting component '" << componentName << "'...");
294 if (!component->startComponent())
295 LOG_WARN("cannot start component '" << componentName << "'. It can already be started");
296
297 return true;
298}
299
300bool ComponentManager::stop()
301{
302 LOG_TRACE("stop()");
303
304 bool result = true;
305 for (ComponentMap::iterator it = componentMap_.begin(); it != componentMap_.end(); ++it)
306 result &= stop(it.key());
307
308 return result;
309}
310
311bool ComponentManager::stop(const QString& componentName)
312{
313 LOG_TRACE("stop(component=" << componentName << ")");
314
315 ComponentBase* component = getComponent(componentName);
316 if (!component)
317 {
318 LOG_WARN("cannot stop component '" << componentName << "'" << ". It does not exist");
319 return false;
320 }
321
322 LOG_INFO("stopping component '" << componentName << "'...");
323 if (!component->stopComponent())
324 LOG_WARN("cannot stop component '" << componentName << "'" << ". It can be already stopped");
325
326 return true;
327}
328
329ComponentBase* ComponentManager::getComponent(const QString& name)
330{
331 LOG_TRACE("getComponent(name=" << name << ")");
332
333 ComponentMap::iterator it = componentMap_.find(name);
334 if (it != componentMap_.end())
335 return *it;
336
337 LOG_WARN("cannot retrieve component '" << name << "'" << ". It does not exist");
338 return NULL;
339}
340
341QStringList ComponentManager::getAllComponentsName() const
342{
343 LOG_TRACE("getAllComponentsName()");
344 return xmlTree_->getAllComponents();
345}
Note: See TracBrowser for help on using the repository browser.