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

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

Added: automated license updating lines:
%pacpus:license{
%pacpus:license}

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