started on RouterFleXML class, still shaky and rudimentary
[metaproxy-moved-to-github.git] / src / router_flexml.hpp
1 /* $Id: router_flexml.hpp,v 1.1 2005-10-26 14:12:00 marc Exp $
2    Copyright (c) 2005, Index Data.
3
4 %LICENSE%
5  */
6
7 #include <iostream>
8 #include <stdexcept>
9
10 #include <libxml/xmlversion.h>
11 #include <libxml/parser.h>
12 #include <libxml/tree.h>
13 #include <libxml/xmlIO.h>
14 #include <libxml/xmlreader.h>
15 //#include <libxslt/transform.h>
16
17 namespace yp2 
18 {
19     
20
21 class RouterFleXML 
22 {
23 public:
24     RouterFleXML(std::string xmlconf) 
25         :  m_xmlconf(""), m_xinclude(false), m_xmlconf_doc(0)
26         {            
27             LIBXML_TEST_VERSION;
28         
29             m_xmlconf = xmlconf;
30             m_xinclude = false;
31
32             m_xmlconf_doc 
33                 = xmlParseMemory(m_xmlconf.c_str(), m_xmlconf.size());
34
35             parse_xml_config_dom();
36             //parse_xml_config_xmlreader();
37         }
38     ~RouterFleXML()
39         {
40             xmlFreeDoc(m_xmlconf_doc);
41         }
42     
43     
44 private:
45     std::string m_xmlconf;
46     bool m_xinclude;
47     xmlDoc * m_xmlconf_doc;
48
49     void xml_dom_error ( xmlNode* node, std::string msg)
50         {
51             std::cerr << "ERROR: " << msg << " "
52                       << node->name << " "
53                       << std::endl;
54         }
55     
56     void parse_xml_config_dom() {   
57     if (m_xmlconf_doc)
58         {
59             xmlNode* root = xmlDocGetRootElement(m_xmlconf_doc);
60             
61             if (std::string((const char *) root->name) != "yp2")
62                 xml_dom_error(root, "expected <yp2>, got ");
63
64             
65             for (const struct _xmlAttr *attr = root->properties; attr; attr = attr->next)
66             {
67                 if (std::string((const char *)attr->name) == "xmlns")
68                 {
69                     const xmlNode *val = attr->children;
70                     //BOOST_CHECK_EQUAL(val->type, XML_TEXT_NODE);
71                     if (std::string((const char *)val->content) 
72                         !=  "http://indexdata.dk/yp2/config/1")
73                         xml_dom_error(root, 
74                                       "expected  xmlns=\"http://indexdata.dk/yp2/config/1\", got ");
75                 }  
76             }
77             std::cout << "GOT HERE" << std::endl;
78
79         }
80     }
81     
82     
83 #if 0
84     void parse_xml_config_xmlreader() {   
85
86         xmlTextReader* reader;
87         //reader->SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1);
88         int ret;
89         //reader = xmlReaderForFile(m_xmlconf.c_str(), NULL, 0);
90         reader = xmlReaderWalker(m_xmlconf_doc);
91  
92         if (reader == NULL) {
93             std::cerr << "failed to read XML config file "
94                       << std::endl
95                       << m_xmlconf << std::endl;
96             std::exit(1);
97         }
98
99
100         // root element processing
101         xml_progress_deep_to_element(reader);
102         if (std::string("yp2") != (const char*)xmlTextReaderConstName(reader))
103             xml_error(reader, "root element must be named <yp2>");
104
105         std::cout << "<" << xmlTextReaderConstName(reader);
106
107         //if (xmlTextReaderHasAttributes(reader))
108         //if ((!xmlTextReaderMoveToAttributeNs(reader, NULL,
109         //                         (const xmlChar*)"http://indexdata.dk/yp2/config/1" )))
110         if ((!xmlTextReaderMoveToFirstAttribute(reader))
111           || (! xmlTextReaderIsNamespaceDecl(reader))
112           || (std::string("http://indexdata.dk/yp2/config/1") 
113               != (const char*)xmlTextReaderConstValue(reader)))
114             xml_error(reader, "expected root element <yp2> in namespace "
115                       "'http://indexdata.dk/yp2/config/1'");
116
117         std::cout << " " << xmlTextReaderConstName(reader) << "=\""  
118                   << xmlTextReaderConstValue(reader) << "\">"  
119             //<< xmlTextReaderIsNamespaceDecl(reader)
120                   << std::endl;
121
122
123         // start element processing
124         xml_progress_deep_to_element(reader);
125         if (std::string("start") != (const char*)xmlTextReaderConstName(reader)
126             || !xmlTextReaderMoveToFirstAttribute(reader)
127             || std::string("route") != (const char*)xmlTextReaderConstName(reader)
128             )
129             xml_error(reader, "start element <start route=\"route_id\"/> expected");
130
131         std::cout << "<start " << xmlTextReaderConstName(reader) <<  "=\"" 
132                   <<  xmlTextReaderConstValue(reader) << "\"/>" << std::endl;
133              //<< xmlTextReaderGetAttribute(reader, (const xmlChar *)"route") 
134
135
136         // filters element processing
137         xml_progress_flat_to_element(reader);
138         
139         if (std::string("filters") != (const char*)xmlTextReaderConstName(reader)
140             )
141             xml_error(reader, "filters element <filters> expected");
142
143         std::cout << "<filters>" << std::endl;
144                   
145
146         // filter element processing
147         xml_progress_deep_to_element(reader);
148         if (std::string("filter") != (const char*)xmlTextReaderConstName(reader)
149             )
150             xml_error(reader, "filter element <filter id=\"some_id\" "
151                       "type=\"some_type\"/> expected");
152
153         while (std::string("filter") == (const char*)xmlTextReaderConstName(reader)){
154             std::string filter_id;
155             std::string filter_type;
156             if (!xmlTextReaderMoveToFirstAttribute(reader)
157                 || std::string("id") != (const char*)xmlTextReaderConstName(reader))
158                 xml_error(reader, "filter element <filter id=\"some_id\" "
159                           "type=\"some_type\"/> expected");
160             filter_id = (const char*)xmlTextReaderConstValue(reader);
161             if (!xmlTextReaderMoveToNextAttribute(reader)
162                 || std::string("type") != (const char*)xmlTextReaderConstName(reader))
163                 xml_error(reader, "filter element <filter id=\"some_id\" "
164                           "type=\"some_type\"/> expected");
165             filter_type = (const char*)xmlTextReaderConstValue(reader);
166             std::cout << "<filter id=\"" << filter_id 
167                       << "\" type=\"" << filter_type << "\"/>" 
168                       << std::endl;
169             xml_progress_flat_to_element(reader);
170         }
171
172         std::cout << "</filters>" << std::endl;
173
174
175         // routes element processing
176         // xml_progress_flat_to_element(reader);
177         if (std::string("routes") != (const char*)xmlTextReaderConstName(reader)
178             )
179             xml_error(reader, "routes element <routes> expected");
180
181         std::cout << "<routes>" << std::endl;
182         // route element processing
183         xml_progress_deep_to_element(reader);
184         if (std::string("route") != (const char*)xmlTextReaderConstName(reader)
185             )
186             xml_error(reader, "route element <route id=\"some_id\" "
187                       "type=\"some_type\"/> expected");
188         while (std::string("route") == (const char*)xmlTextReaderConstName(reader)){
189             std::string route_id;
190             if (!xmlTextReaderMoveToFirstAttribute(reader)
191                 || std::string("id") != (const char*)xmlTextReaderConstName(reader))
192                 xml_error(reader, "route element <route id=\"some_id\"/> expected");
193             route_id = (const char*)xmlTextReaderConstValue(reader);
194
195
196             std::cout << "<route id=\"" << route_id << "\">" << std::endl;
197             std::cout << "</route>" << std::endl;
198             xml_progress_flat_to_element(reader);
199         }
200
201         std::cout << "</routes>" << std::endl;
202
203         std::cout << "</yp2>" << std::endl;
204
205         xml_debug_print(reader);
206
207
208         // freeing C xml reader libs
209         xmlFreeTextReader(reader);
210         if (ret != 0) {
211             std::cerr << "Parsing failed of XML configuration" 
212                       << std::endl 
213                       << m_xmlconf << std::endl;
214             std::exit(1);
215         }
216     }
217
218     void xml_error ( xmlTextReader* reader, std::string msg)
219         {
220             std::cerr << "ERROR: " << msg << " "
221                       << xmlTextReaderGetParserLineNumber(reader) << ":" 
222                       << xmlTextReaderGetParserColumnNumber(reader) << " " 
223                       << xmlTextReaderConstName(reader) << " "  
224                       << xmlTextReaderDepth(reader) << " " 
225                       << xmlTextReaderNodeType(reader) << std::endl;
226         }
227     
228     void xml_debug_print ( xmlTextReader* reader)
229         {
230         // processing all other elements
231         //while (xmlTextReaderMoveToElement(reader)) // reads next element ??
232         //while (xmlTextReaderNext(reader)) //does not descend, keeps level 
233         while (xmlTextReaderRead(reader)) // descends into all subtree nodes
234             std::cout << xmlTextReaderGetParserLineNumber(reader) << ":" 
235                       << xmlTextReaderGetParserColumnNumber(reader) << " " 
236                       << xmlTextReaderDepth(reader) << " " 
237                       << xmlTextReaderNodeType(reader) << " "
238                       << "ConstName " << xmlTextReaderConstName(reader) << " "
239                       << std::endl;
240         }
241     
242     bool xml_progress_deep_to_element(xmlTextReader* reader)
243         {
244             bool ret = false;
245             while(xmlTextReaderRead(reader) 
246                   && xmlTextReaderNodeType(reader) !=  XML_ELEMENT_NODE
247                   && !( xmlTextReaderNodeType(reader) 
248                         == XML_READER_TYPE_END_ELEMENT
249                         && 0 == xmlTextReaderDepth(reader))
250                 ) 
251                 ret = true;
252             return ret;
253         }
254     
255     bool xml_progress_flat_to_element(xmlTextReader* reader)
256         {
257             bool ret = false;
258             
259             while(xmlTextReaderNext(reader) 
260                   && xmlTextReaderNodeType(reader) != XML_ELEMENT_NODE
261                   && !( xmlTextReaderNodeType(reader) 
262                         == XML_READER_TYPE_END_ELEMENT
263                         && 0 == xmlTextReaderDepth(reader))
264                 ) {    
265                 ret = true;
266             }
267             return ret;
268         }
269     
270 #endif
271
272 };
273  
274 };
275
276
277 /*
278  * Local variables:
279  * c-basic-offset: 4
280  * indent-tabs-mode: nil
281  * c-file-style: "stroustrup"
282  * End:
283  * vim: shiftwidth=4 tabstop=8 expandtab
284  */