Blame view

src/XMLConfigurator/NodeCfg.cc 3.96 KB
fbe3c2bb   Benjamin Renard   First commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
 * NodeCfg.cc
 *
 *  Created on: 22 oct. 2012
 *      Author: AKKA IS
 */

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

#include <boost/algorithm/string.hpp>

    using namespace std;
    using namespace boost;

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

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

namespace AMDA
{
  namespace XMLConfigurator
  {
    //TODO Push log into log4cxx http://stackoverflow.com/questions/12107423/libxml2-get-validation-errors
    //http://xml.developpez.com/telecharger/detail/id/2561/Comment-valider-un-XML-via-un-XSD-en-C-avec-libXML2
    //http://knol2share.blogspot.fr/2009/05/validate-xml-against-xsd-in-c.html
    //http://wiki.njh.eu/XML-Schema_validation_with_libxml2
    int NodeCfg::getIsValid(const xmlNodePtr elem, const char *schema_filename)
    {
      xmlDocPtr schema_doc = xmlReadFile(schema_filename, NULL, XML_PARSE_NONET);
      if (schema_doc == NULL)
        {
          std::cerr << "the schema cannot be loaded or is not well-formed" << std::endl;
          return -1;
        }

      xmlSchemaParserCtxtPtr parser_ctxt = xmlSchemaNewDocParserCtxt(schema_doc);
      if (parser_ctxt == NULL)
        {
           std::cerr << "unable to create a parser context for the schema" << std::endl;
          xmlFreeDoc(schema_doc);
          return -2;
        }

      xmlSchemaPtr schema = xmlSchemaParse(parser_ctxt);
      if (schema == NULL)
        {
          std::cerr << "the schema itself is not valid" << std::endl;
          xmlSchemaFreeParserCtxt(parser_ctxt);
          xmlFreeDoc(schema_doc);
          return -3;
        }

      xmlSchemaValidCtxtPtr valid_ctxt = xmlSchemaNewValidCtxt(schema);
      if (valid_ctxt == NULL)
        {
          std::cerr << "unable to create a validation context for the schema" << std::endl;
          xmlSchemaFree(schema);
          xmlSchemaFreeParserCtxt(parser_ctxt);
          xmlFreeDoc(schema_doc);
          return -4;
        }

      int is_valid = (xmlSchemaValidateOneElement(valid_ctxt, elem) == 0);

      xmlSchemaFreeValidCtxt(valid_ctxt);
      xmlSchemaFree(schema);
      xmlSchemaFreeParserCtxt(parser_ctxt);
      xmlFreeDoc(schema_doc);

      /* force the return value to be non-negative on success */
      return is_valid ? 1 : 0;
    }

    void NodeGrpCfg::proceed(xmlNodePtr pNode, const AMDA::Parameters::CfgContext& pCtx)
    {
      xmlNodePtr lNode = pNode->xmlChildrenNode;
      while (lNode)
        {
          if ( xmlStrcmp(lNode->name, (const xmlChar *) "text") != 0)
            {
              CfgChildList::iterator it = _cfgChildList.find( std::string((const char*) lNode->name));
              if (it != _cfgChildList.end())
                {
                  it->second->proceed(lNode, pCtx);
                }
bbc17a13   Benjamin Renard   Do not show warni...
92
93
              else if (lNode->type != XML_COMMENT_NODE) 
                { //skip warning on comment
fbe3c2bb   Benjamin Renard   First commit
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
                  LOG4CXX_WARN( gLogger, WARNING_NODE_NOT_SUPPORTED << (const char*) lNode->name);
                }
            }
          lNode = lNode->next;
        }
    }

		void NodeGrpCfg::addNodeParser( const char* pXPath, NodeCfgSPtr pNode) {
			addNodeParser( &_cfgChildList, pXPath, pNode);
		}

		void NodeGrpCfg::addNodeParser( CfgChildList* lChildList, const char* pXPath, NodeCfgSPtr pNode) {
		  std::string lXPath = pXPath;
		  NodeGrpCfg* lCurNode = NULL;
		  std::vector <std::string> fields;
		  boost::split( fields, lXPath, boost::is_any_of( "/" ) );
		  int lNbField = fields.size();
		  bool cont = true;
		  for (int i = 0; cont && i < lNbField; ++i) {
			  if ( (i+1) == lNbField) {
				  (*lChildList)[fields[i]]=pNode;
				  cont=false;
			  } else {
				  if((lCurNode = dynamic_cast<NodeGrpCfg*>((*lChildList)[fields[i]].get()))) {
					  lChildList = &lCurNode->getChildList();
				  } else {
					  ERROR_EXCEPTION( "XMLParameterConfigurator::addNode not found group node: " << fields[i]);
				  }
			  }
		  }
	  }


  } /* namespace XMLConfigurator */
} /* namespace AMDA */