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

Last change on this file since 65 was 64, checked in by Marek Kurdej, 12 years ago

Modified property: added svn:keywords=Id.

  • Property svn:keywords set to Id
File size: 10.3 KB
RevLine 
[62]1// This file is part of the PACPUS framework distributed under the
2// CECILL-C License, Version 1.0.
3//
4/// @version $Id: ComponentManager.cpp 64 2013-01-09 16:41:12Z kurdejma $
[3]5
[31]6#include <Pacpus/kernel/ComponentManager.h>
7#include <Pacpus/kernel/ComponentBase.h>
8#include <Pacpus/kernel/Log.h>
9
[15]10using namespace pacpus;
[3]11
12DECLARE_STATIC_LOGGER("pacpus.core.ComponentManager");
13
14ComponentManager * ComponentManager::mInstance = NULL;
15
16ComponentManager * ComponentManager::create()
17{
18 return getInstance();
19}
20
21ComponentManager * ComponentManager::getInstance()
22{
23 LOG_TRACE("getInstance()");
24 LOG_TRACE("before: mInstance = " << mInstance);
[47]25
26 if (!mInstance)
27 {
[3]28 LOG_INFO("creating new instance...");
29 mInstance = new ComponentManager();
30 LOG_DEBUG("mInstance = " << mInstance);
31 }
[47]32
[3]33 LOG_TRACE("after: mInstance = " << mInstance);
34 return mInstance;
35}
36
37void ComponentManager::destroy()
38{
39 LOG_TRACE("destroy");
40
41 delete mInstance;
42 mInstance = NULL;
43}
44
45ComponentManager::ComponentManager()
46{
47 LOG_TRACE("constructor");
48
49 xmlTree_ = XmlConfigFile::create();
50 LOG_DEBUG("component manager was created");
51}
52
53ComponentManager::~ComponentManager()
54{
55 LOG_TRACE("destructor");
56
57 QMutableMapIterator<ComponentMap::key_type, ComponentMap::mapped_type> it(componentMap_);
[47]58 while (it.hasNext())
[3]59 unRegisterComponent(it.next().key());
[47]60
[3]61 LOG_DEBUG("component manager was deleted");
62}
63
[16]64bool ComponentManager::registerComponentFactory(ComponentFactoryBase* addr, const QString& type)
[3]65{
66 LOG_TRACE("registerComponentFactory(type="<< type << ")");
67
[47]68 if (factoryMap_.contains(type))
69 {
70 LOG_WARN("cannot register a component factory of type '" << type << "'. It already belongs to the manager");
[3]71 return false;
72 }
73
74 factoryMap_[type] = addr;
[47]75 LOG_INFO("registered component factory '" << type << "'");
76
[3]77 return true;
78}
79
[16]80bool ComponentManager::unRegisterComponentFactory(const QString& type)
[3]81{
82 LOG_TRACE("unRegisterComponentFactory(type="<< type << ")");
83
[47]84 if (!factoryMap_.contains(type))
85 {
86 LOG_WARN("cannot unregister component factory '" << type << "'. It was not registered");
[3]87 return false;
88 }
[47]89
[3]90 factoryMap_.remove(type);
[47]91 LOG_INFO("unregistered component factory '" << type << "'");
92
[3]93 return true;
94}
95
[16]96bool ComponentManager::registerComponent(ComponentBase* addr, const QString& name)
[3]97{
98 LOG_TRACE("registerComponent(name="<< name << ")");
99
[47]100 if (componentMap_.contains(name))
101 {
102 LOG_WARN("cannot register component '" << name << "'. A component with the same name exists already");
[3]103 return false;
104 }
[47]105
[3]106 componentMap_[name] = addr;
[47]107 LOG_INFO("registered component " << name);
108
[3]109 return true;
110}
111
[16]112bool ComponentManager::unRegisterComponent(const QString& name)
[3]113{
114 LOG_TRACE("unRegisterComponent(name="<< name << ")");
115
[47]116 if (!componentMap_.contains(name))
117 {
118 LOG_WARN("cannot unregister component '" << name << "'. It was not registered");
[3]119 return false;
120 }
[47]121
[3]122 // FIXME: delete component
123 //delete componentMap_[name];
124 componentMap_.remove(name);
[47]125 LOG_INFO("unregistered component '" << name << "'");
126
[3]127 return true;
128}
129
[16]130bool ComponentManager::createComponent(const QString& type, const QString& name)
[3]131{
132 LOG_TRACE("createComponent(type=" << type << ", " << "name="<< name << ")");
133
[47]134 FactoryMap::iterator it = factoryMap_.find(type);
135 if (it != factoryMap_.end())
136 {
137 (*it)->addComponent(name);
138 return true;
[3]139 }
[47]140
[3]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
[16]148bool ComponentManager::loadPlugin(const QString& filename)
[3]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
[16]175std::size_t ComponentManager::loadComponents(const QString& configFilename)
[3]176{
177 LOG_TRACE("loadComponents(filename=" << configFilename << ")");
178
179 // load the components tree in memory
[47]180 xmlTree_->loadFile(configFilename);
[3]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
[47]266bool ComponentManager::start()
[3]267{
268 LOG_TRACE("start()");
269
270 bool result = true;
[47]271 for (ComponentMap::iterator it = componentMap_.begin(), itend = componentMap_.end(); it != itend; ++it )
272 result &= start(it.key());
273
[3]274 return result;
275}
276
[47]277bool ComponentManager::start(const QString& componentName)
[3]278{
279 LOG_TRACE("start(component=" << componentName << ")");
280
[47]281 ComponentBase* component = getComponent(componentName);
282 if (!component)
283 {
284 LOG_WARN("cannot start component '" << componentName << "'. It does not exist!");
[3]285 return false;
286 }
287
288 LOG_INFO("starting component '" << componentName << "'...");
[47]289 if (!component->startComponent())
290 LOG_WARN("cannot start component '" << componentName << "'. It can already be started");
291
[3]292 return true;
293}
294
[47]295bool ComponentManager::stop()
[3]296{
297 LOG_TRACE("stop()");
298
299 bool result = true;
[47]300 for (ComponentMap::iterator it = componentMap_.begin(); it != componentMap_.end(); ++it)
301 result &= stop(it.key());
302
[3]303 return result;
304}
305
[47]306bool ComponentManager::stop(const QString& componentName)
[3]307{
308 LOG_TRACE("stop(component=" << componentName << ")");
309
[47]310 ComponentBase* component = getComponent(componentName);
311 if (!component)
312 {
313 LOG_WARN("cannot stop component '" << componentName << "'" << ". It does not exist");
[3]314 return false;
315 }
316
317 LOG_INFO("stopping component '" << componentName << "'...");
[47]318 if (!component->stopComponent())
319 LOG_WARN("cannot stop component '" << componentName << "'" << ". It can be already stopped");
320
[3]321 return true;
322}
323
[16]324ComponentBase* ComponentManager::getComponent(const QString& name)
[3]325{
326 LOG_TRACE("getComponent(name=" << name << ")");
327
[47]328 ComponentMap::iterator it = componentMap_.find(name);
329 if (it != componentMap_.end())
330 return *it;
331
332 LOG_WARN("cannot retrieve component '" << name << "'" << ". It does not exist");
333 return NULL;
[3]334}
335
[47]336QStringList ComponentManager::getAllComponentsName() const
[3]337{
338 LOG_TRACE("getAllComponentsName()");
339 return xmlTree_->getAllComponents();
340}
Note: See TracBrowser for help on using the repository browser.