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

Last change on this file since 109 was 91, checked in by DHERBOMEZ Gérald, 12 years ago

Improvement of the build system to avoid some workarounds

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