source: pacpusframework/branches/2.0-beta1/src/PacpusLib/XmlConfigFile.cpp@ 163

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

Added: scripts to create new component.

  • Property svn:executable set to *
File size: 12.0 KB
RevLine 
[89]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: XmlConfigFile.cpp 76 2013-01-10 17:05:10Z kurdejma $
6
7#include <Pacpus/kernel/XmlConfigFile.h>
[146]8
[89]9#include <Pacpus/kernel/Log.h>
10
11#include <QFile>
12#include <QTextStream>
13
[146]14////////////////////////////////////////////////////////////////////////////////
15
[89]16using namespace pacpus;
17using namespace std;
18
19DECLARE_STATIC_LOGGER("pacpus.core.XmlConfigFile");
20
[146]21XmlConfigFile * XmlConfigFile::m_xmlConfigFile = NULL;
[89]22
[147]23static const char * kXmlConfigFilename = "pacpus_config.xml";
[89]24
[146]25static const char * kRootSection = "pacpus";
[89]26
[146]27static const char * kComponentSection = "components";
28static const char * kConnectionSection = "connections";
29static const char * kParameterSection = "parameters";
30
31static const char * kComponentNode = "component";
32static const char * kConnectionNode = "connection";
33static const char * kPluginNode = "plugin";
34
35static const char * kNameAttribute = "name"; // <component name="MyComponent1" type="MyComponentType"/>
36static const char * kLibAttribute = "lib"; // <plugin lib="MyLibrary.dll"/>
37static const char * kExtensionAttribute = "extension"; // <parameter extension=".dll">
38static const char * kPrefixAttribute = "prefix"; // <parameter prefix="lib">
39static const char * kPostfixAttribute = "postfix"; // <parameter postfix="_d">
40
41////////////////////////////////////////////////////////////////////////////////
42// helper method
43QDomNode getNamedItemFromDomDocument(const QDomDocument & document, const char * itemName);
44
45////////////////////////////////////////////////////////////////////////////////
46
47// CTOR/DTOR
[89]48XmlConfigFile::XmlConfigFile()
[146]49 : m_numberOfComponents(0)
[89]50{
51 LOG_TRACE("constructor");
52
53 // create the root of the XML tree
[146]54 m_document.appendChild(m_document.createElement(kRootSection));
[89]55 // create the sections
[146]56 m_document.documentElement().appendChild(m_document.createElement(kParameterSection));
57 m_document.documentElement().appendChild(m_document.createElement(kComponentSection));
58 m_document.documentElement().appendChild(m_document.createElement(kConnectionSection));
[147]59 m_file.setFileName(kXmlConfigFilename);
[146]60 bool isOpenedSuccessfully = m_file.open(QIODevice::ReadWrite); // FIXME: ReadOnly ?
61 if (isOpenedSuccessfully) {
62 LOG_INFO("XML document " << kXmlConfigFilename << " was created");
[89]63 } else {
[146]64 LOG_ERROR("cannot open XML document " << kXmlConfigFilename);
65 throw "cannot open XML document file";
[89]66 }
67}
68
69XmlConfigFile::~XmlConfigFile()
70{
71 LOG_TRACE("destructor");
72}
73
[146]74// CREATE/DESTROY
[89]75XmlConfigFile * XmlConfigFile::create()
76{
[146]77 if (NULL ==m_xmlConfigFile) {
78 m_xmlConfigFile = new XmlConfigFile();
[89]79 }
[146]80 return m_xmlConfigFile;
[89]81}
82
83void XmlConfigFile::destroy()
84{
[146]85 delete m_xmlConfigFile;
86 m_xmlConfigFile = NULL;
[89]87}
88
[146]89// COMPONENTS ADD/REMOVE/CREATE
[89]90void XmlConfigFile::addComponent(QDomElement component)
91{
[146]92 QMutexLocker mutexLocker(&m_mutex); // locks mutex, unlocks it in destructor
93 (void) mutexLocker; // unused
94
95 // TODO: change .tagName => .attribute(kPropertyComponentName.c_str())
96 QDomNode componentSectionNode = getNamedItemFromDomDocument(m_document, kComponentSection);
97 if (componentSectionNode.namedItem(component.attribute(kNameAttribute)/*.tagName()*/).isNull()) {
98 LOG_WARN("component " << component.attribute(kNameAttribute)/*tagName()*/ << " exists already in the document");
[89]99 } else {
[146]100 QDomNode node = getNamedItemFromDomDocument(m_document, kComponentSection).appendChild(component);
101 ++m_numberOfComponents;
[89]102 LOG_INFO("component " << node.nodeName() << " has been added to the section "
[146]103 << getNamedItemFromDomDocument(m_document, kComponentSection).nodeName());
[89]104 }
105}
106
107void XmlConfigFile::delComponent(QDomElement component)
108{
[146]109 removeComponent(component);
110}
[89]111
[146]112void XmlConfigFile::removeComponent(QDomElement component)
113{
114 QMutexLocker mutexLocker(&m_mutex); // locks mutex, unlocks it in destructor
115 (void) mutexLocker; // unused
116
117 QDomNode node = getNamedItemFromDomDocument(m_document, kComponentSection).removeChild(component);
[89]118 if (node.isNull()) {
[146]119 LOG_WARN("component " << component.attribute(kNameAttribute)/*tagName()*/ << " doesn't exist in the document.");
[89]120 } else {
121 LOG_INFO("component " << node.nodeName() << " has been removed from the section "
[146]122 << getNamedItemFromDomDocument(m_document, kComponentSection).nodeName());
123 --m_numberOfComponents;
[89]124 }
125}
126
127QDomElement XmlConfigFile::createComponent(QString name)
128{
129 LOG_DEBUG("creating component " << name);
130
[146]131 QMutexLocker mutexLocker(&m_mutex); // locks mutex, unlocks it in destructor
132 (void) mutexLocker; // unused
133 return m_document.createElement(name);
[89]134}
135
[146]136// FILE I/O
[89]137void XmlConfigFile::saveFile(QString fileName)
138{
[146]139 QMutexLocker mutexLocker(&m_mutex);
140 (void) mutexLocker; // unused
[89]141
[146]142 m_file.close();
143 assert(!m_file.isOpen());
144 m_file.setFileName(fileName);
[89]145 {
[146]146 // open file
147 bool isOpenedSuccessfully = m_file.open(QIODevice::WriteOnly);
148 if (!isOpenedSuccessfully) {
149 LOG_ERROR("cannot open file '" << m_file.fileName() << "' for writing");
150 return;
[89]151 }
[146]152 QTextStream ts(&m_file);
153 ts << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
154 ts << m_document.toString();
155 m_file.close();
[89]156 }
[146]157 LOG_DEBUG("file \"" << m_file.fileName() << "\" has been saved");
[89]158}
159
160int XmlConfigFile::loadFile(QString fileName)
161{
[146]162 // lock access
163 QMutexLocker mutexLocker(&m_mutex);
164 (void) mutexLocker; // unused
[89]165
[146]166 // check if there are components already
167 if (0 != m_numberOfComponents) {
168 LOG_WARN("XML document contained " << m_numberOfComponents << " components that will be lost!");
[89]169 }
170
[146]171 m_file.close();
172 assert(!m_file.isOpen());
173 m_file.setFileName(fileName);
174 {
175 // open file
176 bool isOpenedSuccessfully = m_file.open(QIODevice::ReadOnly);
177 if (!isOpenedSuccessfully) {
178 LOG_ERROR("cannot open file '" << m_file.fileName() << "' for reading");
179 return 0;
180 }
181 // read and parse input XML file
182 QString errorMsg;
183 int errorLine = 0;
184 int errorColumn = 0;
185 if (!m_document.setContent(&m_file, /*namespaceProcessing=*/true, &errorMsg, &errorLine, &errorColumn)) {
186 LOG_ERROR("cannot parse XML file " << m_file.fileName());
187 LOG_ERROR(errorMsg << " at " << errorLine << ":" << errorColumn << " (line:col)");
188 m_file.close();
189 return 0;
190 }
191 // close file
192 m_file.close();
[89]193 }
194
195 // get the number of components in the loaded tree
[146]196 m_numberOfComponents = getAllComponents().count();
[89]197
[146]198 LOG_INFO("XML file \"" << m_file.fileName() << "\" has been loaded. Number of components = " << m_numberOfComponents);
[89]199 LOG_DEBUG("XML file content:\n"
[146]200 << "BEGIN============================================================================\n"
201 << m_document.toString()
202 << "END==============================================================================\n"
203 );
[89]204
[146]205 return m_numberOfComponents;
[89]206}
207
[146]208// COMPONENTS
209QDomNodeList XmlConfigFile::getAllComponents() const
[89]210{
[146]211 // get components section
212 QDomElement componentsElement = getNamedItemFromDomDocument(m_document, kComponentSection).toElement();
213 if (componentsElement.isNull()) {
214 LOG_WARN("there is no '" << kComponentSection << "' section in the XML");
215 return QDomNodeList();
216 }
[89]217
[146]218 // get component nodes
219 return componentsElement.elementsByTagName(kComponentNode);
220}
[89]221
[146]222QStringList XmlConfigFile::getAllComponentsNames() const
223{
224 // get component nodes
225 QDomNodeList componentNodes = getAllComponents();
226 // get component names
227 QStringList componentNameList;
228 for (int i = 0; i < componentNodes.size(); ++i) {
229 QDomElement componentElement = componentNodes.at(i).toElement();
230 componentNameList.append(componentElement.attribute(kNameAttribute));
[89]231 }
[146]232 return componentNameList;
233}
[89]234
[146]235QDomElement XmlConfigFile::getComponent(QString componentName) const
236{
237 LOG_DEBUG("getting component " << componentName);
[89]238
[146]239 QDomNodeList componentNodes = getAllComponents();
240 for (int i = 0; i < componentNodes.size(); ++i) {
241 QDomElement componentElement = componentNodes.at(i).toElement();
242 if (componentName == componentElement.attribute(kNameAttribute)) {
243 return componentElement;
244 }
245 }
246 LOG_WARN("cannot get component " << componentName << ": document does not contain a component with this name");
247
[89]248 return QDomElement();
249}
250
[146]251// CONNECTIONS
252QDomNodeList XmlConfigFile::getAllConnections() const
[89]253{
[146]254 // get connections section
255 QDomElement connectionsElement = getNamedItemFromDomDocument(m_document, kParameterSection).toElement();
256 if (connectionsElement.isNull()) {
257 LOG_WARN("there is no '" << kParameterSection << "' section in the XML");
258 return QDomNodeList();
[89]259 }
[146]260
261 // get connection nodes
262 //return connectionsElement.elementsByTagName(kConnectionNode);
263 return getNamedItemFromDomDocument(m_document, kConnectionSection).childNodes();
[89]264}
265
[146]266QDomElement XmlConfigFile::getConnection(QString name) const
[89]267{
[146]268 LOG_DEBUG("getting connection " << name);
269
270 QDomNodeList connectionNodes = getAllConnections();
271 for (int i = 0; i < connectionNodes.size(); ++i) {
272 QDomElement connectionElement = connectionNodes.at(i).toElement();
273 // TODO: name by attribute 'name'
274 if (name == connectionElement.attribute(kNameAttribute)) {
275 return connectionElement;
276 }
277 }
278 LOG_WARN("cannot get connection " << name << ": document does not contain a connection with this name");
279
280 return QDomElement();
[89]281}
282
[146]283// PLUGINS
284QDomNodeList XmlConfigFile::getAllPlugins()
[89]285{
[146]286 // get parameters section
287 QDomElement parametersElement = getNamedItemFromDomDocument(m_document, kParameterSection).toElement();
288 if (parametersElement.isNull()) {
289 LOG_WARN("there is no '" << kParameterSection << "' section in the XML");
290 return QDomNodeList();
291 }
[89]292
[146]293 // get attributes
294 m_libraryExtension = parametersElement.attribute(kExtensionAttribute);
295 if (!m_libraryExtension.isEmpty()) {
296 // prefix with a dot '.' if there is no one
297 if ('.' != m_libraryExtension.at(0)) {
298 m_libraryExtension = '.' + m_libraryExtension;
299 }
300 }
301 m_libraryPrefix = parametersElement.attribute(kPrefixAttribute);
302 m_libraryPostfix = parametersElement.attribute(kPostfixAttribute);
303
304 // get plugin nodes
305 return parametersElement.elementsByTagName(kPluginNode);
[89]306}
307
[146]308QStringList XmlConfigFile::getAllPluginsNames()
[89]309{
[146]310 QDomNodeList pluginList = getAllPlugins();
311 if (0 == pluginList.size()) {
312 LOG_ERROR("no plugins were specified");
313 return QStringList();
314 }
315
316 // get plugin library paths
317 QStringList pluginLibraryNames;
318 for (int i = 0; i < pluginList.size(); ++i) {
319 QDomElement pluginElement = pluginList.at(i).toElement();
320 QString libraryFileName = libraryPrefix() + pluginElement.attribute(kLibAttribute) + libraryPostfix() + libraryExtension();
321 pluginLibraryNames.append(libraryFileName);
322 }
323 return pluginLibraryNames;
[89]324}
[146]325
326QString XmlConfigFile::libraryExtension() const
327{
328 return m_libraryExtension;
329}
330
331QString XmlConfigFile::libraryPrefix() const
332{
333 return m_libraryPrefix;
334}
335
336QString XmlConfigFile::libraryPostfix() const
337{
338 return m_libraryPostfix;
339}
340
341////////////////////////////////////////////////////////////////////////////////
342// HELPER METHODS
343QDomNode getNamedItemFromDomDocument(const QDomDocument & document, const char * itemName)
344{
345 return document.documentElement().namedItem(itemName);
346}
Note: See TracBrowser for help on using the repository browser.