XMLParameterConfigurator.cc 4.49 KB
/**
 * XMLParameterConfigurator.cc
 *
 *  Created on: 17 oct. 2012
 *      Author: AKKA IS
 */

#include <iostream>
#include <sstream>
#include <string>

#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;

#include "log4cxx/logger.h"

// XML  include
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/xmlstring.h>
#include <libxml/xmlschemas.h>

#include "NodeCfg.hh"
#include "Constant.hh"

#include "ParamNode.hh"
#include "XMLParameterConfigurator.hh"
#include "Config.hh"
#include "ServicesServer.hh"

using namespace log4cxx;
using namespace AMDA::XMLConfigurator;

// Global variable

namespace AMDA {
    namespace XMLParameterConfigurator {
        log4cxx::LoggerPtr gLogger = log4cxx::Logger::getLogger("AMDA-Kernel.XMLParameterConfigurator");

        XMLParameterConfigurator::XMLParameterConfigurator(const char* pXSDFile) : XMLConfigurator(pXSDFile, true) {
            LOG4CXX_DEBUG(gLogger, "XMLParameterConfigurator Constructor")
            getXmlConfiguratorMap()["param"] = RootNodeCfgSPtr(new ParamNode);
        }

        XMLParameterConfigurator::~XMLParameterConfigurator() {
        }

        bool XMLParameterConfigurator::proceed(const char* filename,
                const AMDA::Parameters::CfgContext& pCtx, bool optionalFile) {
                                    // load plugins 
                        AMDA::Parameters::ServicesServer *servicesServer = AMDA::Parameters::ServicesServer::getInstance();
                        servicesServer->loadPluginByType("paramGet");
            xmlDocPtr lDoc = NULL;
            xmlNodePtr lRoot = NULL;
            std::string configurationFileName = this->getParamPath() + "/" + filename
                    + ".xml";
            LOG4CXX_DEBUG(gLogger, "Filename to parse: " << configurationFileName)
            try {
                if (access(configurationFileName.c_str(), F_OK) != 0) {
                    if (optionalFile) {
                        LOG4CXX_WARN(gLogger, "Cannot find file: " << configurationFileName)
                        return false;
                    }
                    ERROR_EXCEPTION(ERROR_FILE_NOT_EXIST << configurationFileName);
                }

                if (!(lDoc = xmlParseFile(configurationFileName.c_str()))) {
                    ERROR_EXCEPTION(ERROR_BAD_XML_FORMAT);
                }

                //  const char* lParamerterXSD = "DataBaseParameters/xsd/parameter.xsd";
                //  if ( ! is_valid( lDoc, lParamerterXSD)) {
                //      ERROR_EXCEPTION( ERROR_DOC_NOT_VALID << " XSD file: " << lParamerterXSD);
                //    }

                if (!(lRoot = xmlDocGetRootElement(lDoc))) {
                    ERROR_EXCEPTION(ERROR_EMPTY_DOCUMENT);
                }
                AMDA::Parameters::CfgContext lContext(pCtx);
                lContext.push<std::string *>(&configurationFileName);

                // XML_XML_ID case
                xmlNs* lNsXML = NULL;
                xmlAttrPtr cur = lRoot->properties;
                while (cur && !lNsXML) {
                    if ((xmlStrEqual(cur->name, (const xmlChar *) "id") == 1) && cur->ns
                            && (xmlStrEqual(cur->ns->prefix, (const xmlChar *) "xml")
                            == 1)) {
                        lNsXML = cur->ns;
                        cur->ns = NULL;
                    } else {
                        cur = cur->next;
                    }
                }
                if (!lNsXML) {
                    ERROR_EXCEPTION(ERROR_MANDATORY_ATTRIBUTE_MISSING << lRoot->name << "@" << XML_XML_ID)
                }

                if (!NodeCfg::getIsValid(lRoot, _XSDFile)) {
                    cur->ns = lNsXML;
                    ERROR_EXCEPTION(ERROR_DOC_NOT_VALID << " XSD file: " << _XSDFile);
                }
                cur->ns = lNsXML;

                RootNodeCfgMap::iterator it = getXmlConfiguratorMap().find(
                        std::string((const char*) lRoot->name));
                if (it != getXmlConfiguratorMap().end()) {
                    it->second->proceed(lRoot, lContext);
                } else {
                    ERROR_EXCEPTION(ERROR_ROOT_NODE_NOT_SUPPORTED << lRoot->name);
                }
            } catch (...) {
                if (lDoc) {
                    xmlFreeDoc(lDoc);
                }
                throw;
            }
            if (lDoc) {
                xmlFreeDoc(lDoc);
            }
            return true;
        }

    } /* namespace  XMLParameterConfigurator*/
} /* namespace AMDA */