Changeset 146 in pacpusframework for branches/2.0-beta1/src/PacpusLib/XmlConfigFile.cpp


Ignore:
Timestamp:
07/31/13 11:20:11 (11 years ago)
Author:
Marek Kurdej
Message:

Update: refactoring in XmlConfigFile.
Added: attributes 'prefix', 'postfix', 'extension' in <parameters>.
Example: <parameters prefix="" postfix="_d" extension="dll">

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.0-beta1/src/PacpusLib/XmlConfigFile.cpp

    r110 r146  
    66
    77#include <Pacpus/kernel/XmlConfigFile.h>
     8
    89#include <Pacpus/kernel/Log.h>
    910
     
    1112#include <QTextStream>
    1213
     14////////////////////////////////////////////////////////////////////////////////
     15
    1316using namespace pacpus;
    1417using namespace std;
     
    1619DECLARE_STATIC_LOGGER("pacpus.core.XmlConfigFile");
    1720
    18 XmlConfigFile * XmlConfigFile::_xmlConfigFile = NULL;
     21XmlConfigFile * XmlConfigFile::m_xmlConfigFile = NULL;
    1922
    2023static const string kPropertyPluginList = "list";
     
    2225static const string kXmlConfigFilename = "pacpus_config.xml";
    2326
    24 #define rootSection "pacpus"
    25 #define componentSection "components"
    26 #define componentNode "component"
    27 #define connectionSection "connections"
    28 #define connectionNode "connection"
    29 #define parameterSection "parameters"
    30 #define pluginNode "plugin"
    31 #define nameAttribute "name"
    32 #define libAttribute "lib"
    33 
     27static const char * kRootSection = "pacpus";
     28
     29static const char * kComponentSection = "components";
     30static const char * kConnectionSection = "connections";
     31static const char * kParameterSection = "parameters";
     32
     33static const char * kComponentNode = "component";
     34static const char * kConnectionNode = "connection";
     35static const char * kPluginNode = "plugin";
     36
     37static const char * kNameAttribute = "name"; // <component name="MyComponent1" type="MyComponentType"/>
     38static const char * kLibAttribute = "lib"; // <plugin lib="MyLibrary.dll"/>
     39static const char * kExtensionAttribute = "extension"; // <parameter extension=".dll">
     40static const char * kPrefixAttribute = "prefix"; // <parameter prefix="lib">
     41static const char * kPostfixAttribute = "postfix"; // <parameter postfix="_d">
     42
     43////////////////////////////////////////////////////////////////////////////////
     44// helper method
     45QDomNode getNamedItemFromDomDocument(const QDomDocument & document, const char * itemName);
     46
     47////////////////////////////////////////////////////////////////////////////////
     48
     49// CTOR/DTOR
    3450XmlConfigFile::XmlConfigFile()
    35     : _file(NULL)
    36     , _numberOfComponents(0)
     51    : m_numberOfComponents(0)
    3752{
    3853    LOG_TRACE("constructor");
    3954
    4055    // create the root of the XML tree
    41     _document.appendChild(_document.createElement(rootSection));
     56    m_document.appendChild(m_document.createElement(kRootSection));
    4257    // create the sections
    43     _document.documentElement().appendChild(_document.createElement(parameterSection));
    44     _document.documentElement().appendChild(_document.createElement(componentSection));
    45     _document.documentElement().appendChild(_document.createElement(connectionSection));
    46     _file = new QFile(kXmlConfigFilename.c_str());
    47     if (NULL != _file) {
    48         LOG_INFO("XML document " << kXmlConfigFilename.c_str() << " was created");
     58    m_document.documentElement().appendChild(m_document.createElement(kParameterSection));
     59    m_document.documentElement().appendChild(m_document.createElement(kComponentSection));
     60    m_document.documentElement().appendChild(m_document.createElement(kConnectionSection));
     61    m_file.setFileName(kXmlConfigFilename.c_str());
     62    bool isOpenedSuccessfully = m_file.open(QIODevice::ReadWrite); // FIXME: ReadOnly ?
     63    if (isOpenedSuccessfully) {
     64        LOG_INFO("XML document " << kXmlConfigFilename << " was created");
    4965    } else {
    50         LOG_WARN("cannot create XML document " << kXmlConfigFilename.c_str());
     66        LOG_ERROR("cannot open XML document " << kXmlConfigFilename);
     67        throw "cannot open XML document file";
    5168    }
    5269}
     
    5774}
    5875
     76// CREATE/DESTROY
    5977XmlConfigFile * XmlConfigFile::create()
    6078{
    61     if (NULL ==_xmlConfigFile) {
    62         _xmlConfigFile = new XmlConfigFile();
    63     }
    64     return _xmlConfigFile;
     79    if (NULL ==m_xmlConfigFile) {
     80        m_xmlConfigFile = new XmlConfigFile();
     81    }
     82    return m_xmlConfigFile;
    6583}
    6684
    6785void XmlConfigFile::destroy()
    6886{
    69     delete _xmlConfigFile;
    70     _xmlConfigFile = NULL;
    71 }
    72 
     87    delete m_xmlConfigFile;
     88    m_xmlConfigFile = NULL;
     89}
     90
     91// COMPONENTS ADD/REMOVE/CREATE
    7392void XmlConfigFile::addComponent(QDomElement component)
    7493{
    75     _mutex.lock();
    76 // TODO change .tagName => .attribute(kPropertyComponentName.c_str())
    77     if (_document.documentElement().namedItem(componentSection).namedItem(component.attribute(nameAttribute)/*.tagName()*/).isNull()) {
    78         LOG_WARN("component " << component.attribute(nameAttribute)/*tagName()*/ << " exists already in the document");
     94    QMutexLocker mutexLocker(&m_mutex); // locks mutex, unlocks it in destructor
     95    (void) mutexLocker; // unused
     96
     97    // TODO: change .tagName => .attribute(kPropertyComponentName.c_str())
     98    QDomNode componentSectionNode = getNamedItemFromDomDocument(m_document, kComponentSection);
     99    if (componentSectionNode.namedItem(component.attribute(kNameAttribute)/*.tagName()*/).isNull()) {
     100        LOG_WARN("component " << component.attribute(kNameAttribute)/*tagName()*/ << " exists already in the document");
    79101    } else {
    80         QDomNode node = _document.documentElement().namedItem(componentSection).appendChild(component);
    81         ++_numberOfComponents;
     102        QDomNode node = getNamedItemFromDomDocument(m_document, kComponentSection).appendChild(component);
     103        ++m_numberOfComponents;
    82104        LOG_INFO("component " << node.nodeName() << " has been added to the section "
    83                  << _document.documentElement().namedItem(componentSection).nodeName());
    84     }
    85     _mutex.unlock();
     105            << getNamedItemFromDomDocument(m_document, kComponentSection).nodeName());
     106    }
    86107}
    87108
    88109void XmlConfigFile::delComponent(QDomElement component)
    89110{
    90     _mutex.lock();
    91 
    92     QDomNode node = _document.documentElement().namedItem(componentSection).removeChild(component);
     111    removeComponent(component);
     112}
     113
     114void XmlConfigFile::removeComponent(QDomElement component)
     115{
     116    QMutexLocker mutexLocker(&m_mutex); // locks mutex, unlocks it in destructor
     117    (void) mutexLocker; // unused
     118
     119    QDomNode node = getNamedItemFromDomDocument(m_document, kComponentSection).removeChild(component);
    93120    if (node.isNull()) {
    94         LOG_WARN("component " << component.attribute(nameAttribute)/*tagName()*/ << " doesn't exist in the document.");
     121        LOG_WARN("component " << component.attribute(kNameAttribute)/*tagName()*/ << " doesn't exist in the document.");
    95122    } else {
    96123        LOG_INFO("component " << node.nodeName() << " has been removed from the section "
    97                  << _document.documentElement().namedItem(componentSection).nodeName());
    98         --_numberOfComponents;
    99     }
    100 
    101     _mutex.unlock();
     124            << getNamedItemFromDomDocument(m_document, kComponentSection).nodeName());
     125        --m_numberOfComponents;
     126    }
    102127}
    103128
     
    106131    LOG_DEBUG("creating component " << name);
    107132
    108     QMutexLocker mutexLocker(&_mutex);
    109     Q_UNUSED(mutexLocker);
    110     return _document.createElement(name);
    111 }
    112 
     133    QMutexLocker mutexLocker(&m_mutex); // locks mutex, unlocks it in destructor
     134    (void) mutexLocker; // unused
     135    return m_document.createElement(name);
     136}
     137
     138// FILE I/O
    113139void XmlConfigFile::saveFile(QString fileName)
    114140{
    115     QMutexLocker mutexLocker(&_mutex);
    116     Q_UNUSED(mutexLocker);
    117 
    118     _file->setFileName(fileName);
     141    QMutexLocker mutexLocker(&m_mutex);
     142    (void) mutexLocker; // unused
     143
     144    m_file.close();
     145    assert(!m_file.isOpen());
     146    m_file.setFileName(fileName);
    119147    {
    120         _file->open(QIODevice::WriteOnly);
    121         {
    122             QTextStream ts(_file);
    123             ts << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" + _document.toString();
    124         }
    125         _file->close();
    126     }
    127     LOG_DEBUG("file \"" << _file->fileName() << "\" has been saved");
     148        // open file
     149        bool isOpenedSuccessfully = m_file.open(QIODevice::WriteOnly);
     150        if (!isOpenedSuccessfully) {
     151            LOG_ERROR("cannot open file '" << m_file.fileName() << "' for writing");
     152            return;
     153        }
     154        QTextStream ts(&m_file);
     155        ts << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
     156        ts << m_document.toString();
     157        m_file.close();
     158    }
     159    LOG_DEBUG("file \"" << m_file.fileName() << "\" has been saved");
    128160}
    129161
    130162int XmlConfigFile::loadFile(QString fileName)
    131163{
    132     QMutexLocker mutexLocker(&_mutex);
    133     Q_UNUSED(mutexLocker);
    134 
    135     int line = 0, col = 0;
    136     QString errorMsg;
    137 
    138     if (_numberOfComponents != 0) {
    139         LOG_WARN("XML document contained " << _numberOfComponents << " components that will be lost!");
    140     }
    141 
    142     _file->setFileName(fileName);
    143     if (!_file->open( QIODevice::ReadOnly )) {
    144         LOG_ERROR("cannot open file " << fileName);
    145         return 0;
    146     }
    147     if (!_document.setContent( _file, true, &errorMsg, &line, &col )) {
    148         LOG_ERROR("cannot get data into the file " << fileName);
    149         LOG_ERROR(errorMsg << " at position " << line << ":" << col << " (line:col)");
    150         _file->close();
    151         return 0;
    152     }
    153     _file->close();
     164    // lock access
     165    QMutexLocker mutexLocker(&m_mutex);
     166    (void) mutexLocker; // unused
     167
     168    // check if there are components already
     169    if (0 != m_numberOfComponents) {
     170        LOG_WARN("XML document contained " << m_numberOfComponents << " components that will be lost!");
     171    }
     172
     173    m_file.close();
     174    assert(!m_file.isOpen());
     175    m_file.setFileName(fileName);
     176    {
     177        // open file
     178        bool isOpenedSuccessfully = m_file.open(QIODevice::ReadOnly);
     179        if (!isOpenedSuccessfully) {
     180            LOG_ERROR("cannot open file '" << m_file.fileName() << "' for reading");
     181            return 0;
     182        }
     183        // read and parse input XML file
     184        QString errorMsg;
     185        int errorLine = 0;
     186        int errorColumn = 0;
     187        if (!m_document.setContent(&m_file, /*namespaceProcessing=*/true, &errorMsg, &errorLine, &errorColumn)) {
     188            LOG_ERROR("cannot parse XML file " << m_file.fileName());
     189            LOG_ERROR(errorMsg << " at " << errorLine << ":" << errorColumn << " (line:col)");
     190            m_file.close();
     191            return 0;
     192        }
     193        // close file
     194        m_file.close();
     195    }
    154196
    155197    // get the number of components in the loaded tree
    156     _numberOfComponents = _document.documentElement().namedItem(componentSection).childNodes().count();
    157 
    158     LOG_INFO("XML file \"" << fileName << "\" has been loaded. Number of components = " << _numberOfComponents);
     198    m_numberOfComponents = getAllComponents().count();
     199
     200    LOG_INFO("XML file \"" << m_file.fileName() << "\" has been loaded. Number of components = " << m_numberOfComponents);
    159201    LOG_DEBUG("XML file content:\n"
    160               << "BEGIN============================================================================\n"
    161               << _document.toString()
    162               << "END==============================================================================\n"
    163               );
    164 
    165     return _numberOfComponents;
    166 }
    167 
    168 QDomElement XmlConfigFile::getComponent(QString componentName)
     202        << "BEGIN============================================================================\n"
     203        << m_document.toString()
     204        << "END==============================================================================\n"
     205        );
     206
     207    return m_numberOfComponents;
     208}
     209
     210// COMPONENTS
     211QDomNodeList XmlConfigFile::getAllComponents() const
     212{
     213    // get components section
     214    QDomElement componentsElement = getNamedItemFromDomDocument(m_document, kComponentSection).toElement();
     215    if (componentsElement.isNull()) {
     216        LOG_WARN("there is no '" << kComponentSection << "' section in the XML");
     217        return QDomNodeList();
     218    }
     219
     220    // get component nodes
     221    return componentsElement.elementsByTagName(kComponentNode);
     222}
     223
     224QStringList XmlConfigFile::getAllComponentsNames() const
     225{
     226    // get component nodes
     227    QDomNodeList componentNodes = getAllComponents();
     228    // get component names
     229    QStringList componentNameList;
     230    for (int i = 0; i < componentNodes.size(); ++i) {
     231        QDomElement componentElement = componentNodes.at(i).toElement();
     232        componentNameList.append(componentElement.attribute(kNameAttribute));
     233    }
     234    return componentNameList;
     235}
     236
     237QDomElement XmlConfigFile::getComponent(QString componentName) const
    169238{
    170239    LOG_DEBUG("getting component " << componentName);
    171240
    172     QDomNodeList nodeList = _document.documentElement().namedItem(componentSection).toElement().elementsByTagName(componentNode);
    173     for (int i = 0; i < _numberOfComponents; i++) {
    174 
    175         if(nodeList.at(i).toElement().attribute(nameAttribute) == componentName)
    176             return nodeList.at(i).toElement();
    177     }
    178 
    179     LOG_WARN("cannot get component " << componentName << ": document does not contain the component");
     241    QDomNodeList componentNodes = getAllComponents();
     242    for (int i = 0; i < componentNodes.size(); ++i) {
     243        QDomElement componentElement = componentNodes.at(i).toElement();
     244        if (componentName == componentElement.attribute(kNameAttribute)) {
     245            return componentElement;
     246        }
     247    }
     248    LOG_WARN("cannot get component " << componentName << ": document does not contain a component with this name");
    180249
    181250    return QDomElement();
    182251}
    183252
    184 QStringList XmlConfigFile::getAllComponentsNames()
    185 {
    186     QStringList componentNameList;   
    187     QDomNodeList nodeList = _document.documentElement().namedItem(componentSection).toElement().elementsByTagName(componentNode);
    188      for (int i = 0; i < _numberOfComponents; i++) {
    189          componentNameList.append(nodeList.at(i).toElement().attribute(nameAttribute));
    190     }
    191     return componentNameList;
    192 }
    193 
    194 QDomNodeList XmlConfigFile::getAllComponents()
    195 {
    196     return _document.documentElement().namedItem(componentSection).toElement().elementsByTagName(componentNode);
    197 }
    198 
    199 QStringList XmlConfigFile::getAllPlugins()
    200 {
    201     QDomNodeList nodeList = _document.documentElement().namedItem(parameterSection).toElement().elementsByTagName(pluginNode);
    202     QStringList stringList;
    203     if(nodeList.size() == 0) {
    204         LOG_WARN("no plugins were specified");
    205     } else
    206         for(int i = 0; i< nodeList.size(); ++i)
    207             stringList.append(nodeList.at(i).toElement().attribute(libAttribute));
    208 
    209     return stringList;
    210 }
    211 
    212 QDomNodeList XmlConfigFile::getAllConnections()
    213 {
    214    return _document.documentElement().namedItem(connectionSection).childNodes();
    215 }
     253// CONNECTIONS
     254QDomNodeList XmlConfigFile::getAllConnections() const
     255{
     256    // get connections section
     257    QDomElement connectionsElement = getNamedItemFromDomDocument(m_document, kParameterSection).toElement();
     258    if (connectionsElement.isNull()) {
     259        LOG_WARN("there is no '" << kParameterSection << "' section in the XML");
     260        return QDomNodeList();
     261    }
     262
     263    // get connection nodes
     264    //return connectionsElement.elementsByTagName(kConnectionNode);
     265    return getNamedItemFromDomDocument(m_document, kConnectionSection).childNodes();
     266}
     267
     268QDomElement XmlConfigFile::getConnection(QString name) const
     269{
     270    LOG_DEBUG("getting connection " << name);
     271
     272    QDomNodeList connectionNodes = getAllConnections();
     273    for (int i = 0; i < connectionNodes.size(); ++i) {
     274        QDomElement connectionElement = connectionNodes.at(i).toElement();
     275        // TODO: name by attribute 'name'
     276        if (name == connectionElement.attribute(kNameAttribute)) {
     277            return connectionElement;
     278        }
     279    }
     280    LOG_WARN("cannot get connection " << name << ": document does not contain a connection with this name");
     281
     282    return QDomElement();
     283}
     284
     285// PLUGINS
     286QDomNodeList XmlConfigFile::getAllPlugins()
     287{
     288    // get parameters section
     289    QDomElement parametersElement = getNamedItemFromDomDocument(m_document, kParameterSection).toElement();
     290    if (parametersElement.isNull()) {
     291        LOG_WARN("there is no '" << kParameterSection << "' section in the XML");
     292        return QDomNodeList();
     293    }
     294
     295    // get attributes
     296    m_libraryExtension = parametersElement.attribute(kExtensionAttribute);
     297    if (!m_libraryExtension.isEmpty()) {
     298        // prefix with a dot '.' if there is no one
     299        if ('.' != m_libraryExtension.at(0)) {
     300            m_libraryExtension = '.' + m_libraryExtension;
     301        }
     302    }
     303    m_libraryPrefix = parametersElement.attribute(kPrefixAttribute);
     304    m_libraryPostfix = parametersElement.attribute(kPostfixAttribute);
     305   
     306    // get plugin nodes
     307    return parametersElement.elementsByTagName(kPluginNode);
     308}
     309
     310QStringList XmlConfigFile::getAllPluginsNames()
     311{
     312    QDomNodeList pluginList = getAllPlugins();
     313    if (0 == pluginList.size()) {
     314        LOG_ERROR("no plugins were specified");
     315        return QStringList();
     316    }
     317
     318    // get plugin library paths
     319    QStringList pluginLibraryNames;
     320    for (int i = 0; i < pluginList.size(); ++i) {
     321        QDomElement pluginElement = pluginList.at(i).toElement();
     322        QString libraryFileName = libraryPrefix() + pluginElement.attribute(kLibAttribute) + libraryPostfix() + libraryExtension();
     323        pluginLibraryNames.append(libraryFileName);
     324    }
     325    return pluginLibraryNames;
     326}
     327
     328QString XmlConfigFile::libraryExtension() const
     329{
     330    return m_libraryExtension;
     331}
     332
     333QString XmlConfigFile::libraryPrefix() const
     334{
     335    return m_libraryPrefix;
     336}
     337
     338QString XmlConfigFile::libraryPostfix() const
     339{
     340    return m_libraryPostfix;
     341}
     342
     343////////////////////////////////////////////////////////////////////////////////
     344// HELPER METHODS
     345QDomNode getNamedItemFromDomDocument(const QDomDocument & document, const char * itemName)
     346{
     347    return document.documentElement().namedItem(itemName);
     348}
Note: See TracChangeset for help on using the changeset viewer.