47501df0ae101e2af7bcfa8ff08c2d35bc81cf6e
[metaproxy-moved-to-github.git] / src / router_flexml.cpp
1 /* $Id: router_flexml.cpp,v 1.6 2005-12-08 22:32:57 adam Exp $
2    Copyright (c) 2005, Index Data.
3
4 %LICENSE%
5  */
6
7 #include "config.hpp"
8 #include "router_flexml.hpp"
9
10 #include <iostream>
11 #include <map>
12 #include <list>
13
14 #include <boost/shared_ptr.hpp>
15
16 #include <libxml/xmlversion.h>
17 #include <libxml/parser.h>
18 #include <libxml/tree.h>
19
20
21 namespace yp2 {
22     class RouterFleXML::Rep {
23         friend class RouterFleXML;
24         Rep();
25
26         typedef std::map<std::string, boost::shared_ptr<const yp2::filter::Base> >
27                 IdFilterMap ;
28         typedef std::list<std::string> FilterIdList;
29         typedef std::map<std::string, FilterIdList > IdRouteMap ;
30
31         bool m_xinclude;
32         IdFilterMap m_id_filter_map;
33         FilterIdList m_filter_id_list;
34         IdRouteMap m_id_route_map;
35
36         void create_filter(std::string type, 
37                            const xmlDoc * xmldoc,
38                            std::string id = "");
39
40         void parse_xml_config_dom(xmlDocPtr doc);
41
42         bool is_element(const xmlNode *ptr, 
43                         const std::string &ns,
44                         const std::string &name);
45         
46         bool is_element_yp2(const xmlNode *ptr, 
47                             const std::string &name);
48
49         bool check_element_yp2(const xmlNode *ptr, 
50                                const std::string &name);
51         
52         const xmlNode* jump_to(const xmlNode* node, int xml_node_type);
53
54         const xmlNode* jump_to_next(const xmlNode* node, int xml_node_type);
55         
56         const xmlNode* jump_to_children(const xmlNode* node, int xml_node_type);
57     };
58 }
59
60 const xmlNode* yp2::RouterFleXML::Rep::jump_to_children(const xmlNode* node, int xml_node_type)
61 {
62     node = node->children;
63     for (; node && node->type != xml_node_type; node = node->next)
64         ;
65     return node;
66 }
67         
68 const xmlNode* yp2::RouterFleXML::Rep::jump_to_next(const xmlNode* node, int xml_node_type)
69 {
70     node = node->next;
71     for (; node && node->type != xml_node_type; node = node->next)
72         ;
73     return node;
74 }
75         
76 const xmlNode* yp2::RouterFleXML::Rep::jump_to(const xmlNode* node, int xml_node_type)
77 {
78     for (; node && node->type != xml_node_type; node = node->next)
79         ;
80     return node;
81 }
82
83 bool yp2::RouterFleXML::Rep::is_element(const xmlNode *ptr, 
84                                         const std::string &ns,
85                                         const std::string &name)
86 {
87     if (ptr && ptr->type == XML_ELEMENT_NODE && ptr->ns && ptr->ns->href 
88         && !xmlStrcmp(BAD_CAST ns.c_str(), ptr->ns->href)
89         && !xmlStrcmp(BAD_CAST name.c_str(), ptr->name))
90         return true;
91     return false;
92 }
93
94 bool yp2::RouterFleXML::Rep::is_element_yp2(const xmlNode *ptr, 
95                                             const std::string &name)
96 {
97     return is_element(ptr, "http://indexdata.dk/yp2/config/1", name);
98 }
99
100 bool yp2::RouterFleXML::Rep::check_element_yp2(const xmlNode *ptr, 
101                                                const std::string &name)
102 {
103     if (!is_element_yp2(ptr, name))
104         throw XMLError("Error. Expected element name " + name);
105     return true;
106 }
107
108 void yp2::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc)
109 {
110     if (!doc)
111         throw XMLError("Empty XML Document");
112     
113     const xmlNode* root = xmlDocGetRootElement(doc);
114     
115     check_element_yp2(root,  "yp2");
116
117     std::cout << "processing /yp2" << std::endl;
118     
119     // process <start> node which is expected first element node
120     const xmlNode* node = jump_to_children(root, XML_ELEMENT_NODE);
121     //for (; node && node->type != XML_ELEMENT_NODE; node = node->next)
122     //    ;
123
124     check_element_yp2(node, "start");
125
126     std::cout << "processing /yp2/start" << std::endl;
127     
128     // process <filters> node which is expected second element node
129     node = jump_to_next(node, XML_ELEMENT_NODE);
130     check_element_yp2(node, "filters");
131     std::cout << "processing /yp2/filters" << std::endl;
132     
133     // process <filter> nodes  in next level
134     const xmlNode* node2 = jump_to_children(node, XML_ELEMENT_NODE);
135     
136     unsigned int filter_nr = 0;
137     while(node2 && check_element_yp2(node2, "filter"))
138     {
139         filter_nr++;
140         std::cout << "processing /yp2/filters/filter[" 
141                   << filter_nr << "]" << std::endl;
142         node2 = jump_to_next(node2, XML_ELEMENT_NODE);
143     }
144     
145     // process <routes> node which is expected third element node
146     node = jump_to_next(node, XML_ELEMENT_NODE);
147     check_element_yp2(node, "routes");
148     std::cout << "processing /yp2/routes" << std::endl;
149     
150     // process <route> nodes  in next level
151     node2 = jump_to_children(node, XML_ELEMENT_NODE);
152     check_element_yp2(node2, "route");
153     
154     unsigned int route_nr = 0;
155     while(is_element_yp2(node2, "router"))
156     {
157         route_nr++;
158         std::cout << "processing /yp2/routes/route[" 
159                   << route_nr << "]" << std::endl;
160         
161         // process <filter> nodes in third level
162         const xmlNode* node3 = jump_to_children(node2, XML_ELEMENT_NODE);
163         
164         unsigned int filter3_nr = 0;
165         while(node3 && check_element_yp2(node3, "filter"))
166         {
167             filter3_nr++;
168             
169             std::cout << "processing /yp2/routes/route[" 
170                       << route_nr << "]/filter[" 
171                       << filter3_nr << "]" << std::endl;
172             
173             node3 = jump_to_next(node3, XML_ELEMENT_NODE);
174             
175         }
176         node2 = jump_to_next(node2, XML_ELEMENT_NODE);
177     }
178 }        
179
180 void yp2::RouterFleXML::Rep::create_filter(std::string type, 
181                                            const xmlDoc * xmldoc,
182                                            std::string id)
183 {
184     std::cout << "Created Filter type='" << type 
185               << "' id='" << id << "'" << std::endl;
186 }
187
188 yp2::RouterFleXML::Rep::Rep() : 
189     m_xinclude(false)
190 {
191 }
192
193 yp2::RouterFleXML::RouterFleXML(std::string xmlconf) 
194     : m_p(new Rep)
195 {            
196     LIBXML_TEST_VERSION;
197     
198     xmlDocPtr doc = xmlParseMemory(xmlconf.c_str(),
199                                    xmlconf.size());
200     if (!doc)
201         throw XMLError("xmlParseMemory failed");
202     else
203     {
204         m_p->parse_xml_config_dom(doc);
205         xmlFreeDoc(doc);
206     }
207 }
208
209 yp2::RouterFleXML::~RouterFleXML()
210 {
211 }
212
213 const yp2::filter::Base *
214 yp2::RouterFleXML::move(const yp2::filter::Base *filter,
215                         const yp2::Package *package) const 
216 {
217     return 0;
218 }
219         
220
221 /*
222  * Local variables:
223  * c-basic-offset: 4
224  * indent-tabs-mode: nil
225  * c-file-style: "stroustrup"
226  * End:
227  * vim: shiftwidth=4 tabstop=8 expandtab
228  */