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

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

Huge commit: use the new includes style in all the files, add the license header in all the headers, and in some cpp.

File size: 10.8 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 if (NULL == mInstance) {
31 LOG_INFO("creating new instance...");
32 mInstance = new ComponentManager();
33 LOG_DEBUG("mInstance = " << mInstance);
34 }
35 LOG_TRACE("after: mInstance = " << mInstance);
36 return mInstance;
37}
38
39void ComponentManager::destroy()
40{
41 LOG_TRACE("destroy");
42
43 delete mInstance;
44 mInstance = NULL;
45}
46
47ComponentManager::ComponentManager()
48{
49 LOG_TRACE("constructor");
50
51 xmlTree_ = XmlConfigFile::create();
52 LOG_DEBUG("component manager was created");
53}
54
55ComponentManager::~ComponentManager()
56{
57 LOG_TRACE("destructor");
58
59 QMutableMapIterator<ComponentMap::key_type, ComponentMap::mapped_type> it(componentMap_);
60 while (it.hasNext()) {
61 unRegisterComponent(it.next().key());
62 }
63 LOG_DEBUG("component manager was deleted");
64}
65
66bool ComponentManager::registerComponentFactory(ComponentFactoryBase* addr, const QString& type)
67{
68 LOG_TRACE("registerComponentFactory(type="<< type << ")");
69
70 if (factoryMap_.contains(type)) {
71 LOG_WARN("cannot register a component factory of type '" << type << "'"
72 << ". It already belongs to the manager"
73 );
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 LOG_WARN("cannot unregister component factory '" << type << "'"
89 << ". It was not registered"
90 );
91 return false;
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 LOG_WARN("cannot register component '" << name << "'"
105 << ". A component with the same name exists already"
106 );
107 return false;
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 LOG_WARN("cannot unregister component '" << name << "'"
121 << ". It was not registered"
122 );
123 return false;
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 if (factoryMap_.contains(type)) {
138 factoryMap_[type]->addComponent(name);
139 return true;
140 }
141 LOG_WARN("cannot create component '" << name << "'"
142 << ". Component factory for type '" << type << "'"
143 << " does not exist or was not registered"
144 );
145 return false;
146}
147
148bool ComponentManager::loadPlugin(const QString& filename)
149{
150 LOG_TRACE("loadPlugin(filename=" << filename << ")");
151
152 pluginLoader_.setFileName(filename);
153
154 if (!pluginLoader_.load()) {
155 LOG_ERROR("cannot load plugin '" << filename << "'"
156 << ". Plugin loader returned error: " << pluginLoader_.errorString()
157 );
158 return false;
159 }
160
161 QObject * plugin = pluginLoader_.instance();
162 if (NULL == plugin) {
163 LOG_WARN("cannot create an instance of the plugin '" << filename << "'"
164 << ". Plugin loader returned error: " << pluginLoader_.errorString()
165 );
166 return false;
167 }
168 pluginList_.append(plugin);
169 LOG_INFO("loaded plugin '" << qobject_cast<PacpusPluginInterface*>(plugin)->name() << "'"
170 << " from file '" << pluginLoader_.fileName() << "'"
171 );
172 return true;
173}
174
175std::size_t ComponentManager::loadComponents(const QString& configFilename)
176{
177 LOG_TRACE("loadComponents(filename=" << configFilename << ")");
178
179 // load the components tree in memory
180 /*int loadedComponentsCount = */xmlTree_->loadFile(configFilename);
181
182 {
183 // Load the plugins containing the components
184 QStringList plugins = xmlTree_->getAllPlugins();
185 Q_FOREACH (QString plugin, plugins) {
186 if (!loadPlugin(plugin)) {
187 LOG_WARN("cannot load plugin '" << plugin << "'");
188 }
189 }
190 }
191
192 QStringList componentsNameList = xmlTree_->getAllComponents();
193 LOG_DEBUG("components in the config file: '" << componentsNameList.join("|") << "'");
194
195 XmlComponentConfig cfg;
196
197 // First, create all the components in the XML list
198 for (QStringList::iterator it = componentsNameList.begin(); it != componentsNameList.end(); ++it) {
199 LOG_DEBUG("try to create component '" << (*it) << "'");
200 cfg.localCopy(xmlTree_->getComponent(*it));
201 QString componentType = cfg.getComponentType();
202 QString componentName = cfg.getComponentName();
203 // create the component and automatically add it to the component manager list
204 if (!createComponent(componentType, componentName)) {
205 LOG_ERROR("cannot create component '" << componentName << "'");
206 continue;
207 }
208 }
209
210 int componentsToConfigureCount = componentMap_.count();
211
212 // Second, try to configure the components without regarding the dependencies
213 for (QStringList::iterator it = componentsNameList.begin(); it != componentsNameList.end(); ++it) {
214 LOG_DEBUG("try to configure component '" << (*it) << "'");
215 cfg.localCopy(xmlTree_->getComponent(*it));
216 QString componentName = cfg.getComponentName();
217
218 // copy locally the config parameters of the component
219 ComponentBase * component = getComponent(componentName);
220 if (NULL == component) {
221 LOG_WARN("component '" << componentName << "' does not exist");
222 } else {
223 component->param.localCopy(cfg.qDomElement());
224 component->configuration_ = component->configureComponent(cfg);
225
226 }
227 } // for
228
229 // Third, if some components requested a delayed configuration, retry
230 for (QStringList::iterator it = componentsNameList.begin(); it != componentsNameList.end() ; ++it) {
231 cfg.localCopy(xmlTree_->getComponent(*it));
232 QString componentName = cfg.getComponentName();
233
234 ComponentBase * component = getComponent(componentName);
235 if (NULL == component) {
236 LOG_WARN("component '" << componentName << "' does not exist");
237 } else {
238 if (component->configuration_ == ComponentBase::CONFIGURATION_DELAYED) {
239 LOG_DEBUG("try to configure component '" << (*it) << "'");
240
241 // copy locally the config parameters of the component
242 component->param.localCopy(cfg.qDomElement());
243 component->configuration_ = component->configureComponent(cfg);
244 }
245
246 if (component->configuration_ == ComponentBase::CONFIGURED_OK) {
247 --componentsToConfigureCount;
248 } else {
249 LOG_ERROR("cannot configure component '" << (*it) << "'"
250 << ". Dependencies with other components are too complex"
251 << ". It was not configured, please review your configuration and/or your component"
252 );
253 component->configuration_ = ComponentBase::CONFIGURED_FAILED;
254 }
255 }
256 } // for
257
258 LOG_INFO(componentMap_.count() << " component(s) were loaded");
259 if (componentsToConfigureCount > 0) {
260 LOG_WARN(componentsToConfigureCount << " component(s) were not configured");
261 }
262
263 return componentMap_.count();
264}
265
266int ComponentManager::start()
267{
268 LOG_TRACE("start()");
269
270 bool result = true;
271 for (ComponentMap::iterator it = componentMap_.begin(), itend = componentMap_.end(); it != itend; ++it ) {
272 result &= (0 < start(it.key()));
273 }
274 return result;
275}
276
277int ComponentManager::start(const QString& componentName)
278{
279 LOG_TRACE("start(component=" << componentName << ")");
280
281 ComponentBase * component = getComponent(componentName);
282 if (NULL == component) {
283 LOG_WARN("cannot start component '" << componentName << "'"
284 << ". It does not exist!"
285 );
286 return false;
287 }
288
289 LOG_INFO("starting component '" << componentName << "'...");
290 if (!component->startComponent()) {
291 LOG_WARN("cannot start component '" << componentName << "'"
292 ". It can already be started"
293 );
294 }
295 return true;
296}
297
298int 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 &= (0 < stop(it.key()));
305 }
306 return result;
307}
308
309int ComponentManager::stop(const QString& componentName)
310{
311 LOG_TRACE("stop(component=" << componentName << ")");
312
313 ComponentBase * component = getComponent(componentName);
314 if (NULL == component) {
315 LOG_WARN("cannot stop component '" << componentName << "'"
316 << ". It does not exist"
317 );
318 return false;
319 }
320
321 LOG_INFO("stopping component '" << componentName << "'...");
322 if (!component->stopComponent()) {
323 LOG_WARN("cannot stop component '" << componentName << "'"
324 << ". It can be already stopped"
325 );
326 }
327 return true;
328}
329
330ComponentBase* ComponentManager::getComponent(const QString& name)
331{
332 LOG_TRACE("getComponent(name=" << name << ")");
333
334 if (!componentMap_.contains(name)) {
335 LOG_WARN("cannot retrieve component '" << name << "'"
336 << ". It does not exist"
337 );
338 return NULL;
339 }
340 return componentMap_[name];
341}
342
343QStringList ComponentManager::getAllComponentsName()
344{
345 LOG_TRACE("getAllComponentsName()");
346
347 return xmlTree_->getAllComponents();
348}
Note: See TracBrowser for help on using the repository browser.