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

Last change on this file since 19 was 16, checked in by sgosseli, 12 years ago

Passage by const-reference instead of value.

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