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

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