1 /* $Id: router_flexml.cpp,v 1.6 2005-12-08 22:32:57 adam Exp $
2 Copyright (c) 2005, Index Data.
8 #include "router_flexml.hpp"
14 #include <boost/shared_ptr.hpp>
16 #include <libxml/xmlversion.h>
17 #include <libxml/parser.h>
18 #include <libxml/tree.h>
22 class RouterFleXML::Rep {
23 friend class RouterFleXML;
26 typedef std::map<std::string, boost::shared_ptr<const yp2::filter::Base> >
28 typedef std::list<std::string> FilterIdList;
29 typedef std::map<std::string, FilterIdList > IdRouteMap ;
32 IdFilterMap m_id_filter_map;
33 FilterIdList m_filter_id_list;
34 IdRouteMap m_id_route_map;
36 void create_filter(std::string type,
37 const xmlDoc * xmldoc,
40 void parse_xml_config_dom(xmlDocPtr doc);
42 bool is_element(const xmlNode *ptr,
43 const std::string &ns,
44 const std::string &name);
46 bool is_element_yp2(const xmlNode *ptr,
47 const std::string &name);
49 bool check_element_yp2(const xmlNode *ptr,
50 const std::string &name);
52 const xmlNode* jump_to(const xmlNode* node, int xml_node_type);
54 const xmlNode* jump_to_next(const xmlNode* node, int xml_node_type);
56 const xmlNode* jump_to_children(const xmlNode* node, int xml_node_type);
60 const xmlNode* yp2::RouterFleXML::Rep::jump_to_children(const xmlNode* node, int xml_node_type)
62 node = node->children;
63 for (; node && node->type != xml_node_type; node = node->next)
68 const xmlNode* yp2::RouterFleXML::Rep::jump_to_next(const xmlNode* node, int xml_node_type)
71 for (; node && node->type != xml_node_type; node = node->next)
76 const xmlNode* yp2::RouterFleXML::Rep::jump_to(const xmlNode* node, int xml_node_type)
78 for (; node && node->type != xml_node_type; node = node->next)
83 bool yp2::RouterFleXML::Rep::is_element(const xmlNode *ptr,
84 const std::string &ns,
85 const std::string &name)
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))
94 bool yp2::RouterFleXML::Rep::is_element_yp2(const xmlNode *ptr,
95 const std::string &name)
97 return is_element(ptr, "http://indexdata.dk/yp2/config/1", name);
100 bool yp2::RouterFleXML::Rep::check_element_yp2(const xmlNode *ptr,
101 const std::string &name)
103 if (!is_element_yp2(ptr, name))
104 throw XMLError("Error. Expected element name " + name);
108 void yp2::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc)
111 throw XMLError("Empty XML Document");
113 const xmlNode* root = xmlDocGetRootElement(doc);
115 check_element_yp2(root, "yp2");
117 std::cout << "processing /yp2" << std::endl;
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)
124 check_element_yp2(node, "start");
126 std::cout << "processing /yp2/start" << std::endl;
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;
133 // process <filter> nodes in next level
134 const xmlNode* node2 = jump_to_children(node, XML_ELEMENT_NODE);
136 unsigned int filter_nr = 0;
137 while(node2 && check_element_yp2(node2, "filter"))
140 std::cout << "processing /yp2/filters/filter["
141 << filter_nr << "]" << std::endl;
142 node2 = jump_to_next(node2, XML_ELEMENT_NODE);
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;
150 // process <route> nodes in next level
151 node2 = jump_to_children(node, XML_ELEMENT_NODE);
152 check_element_yp2(node2, "route");
154 unsigned int route_nr = 0;
155 while(is_element_yp2(node2, "router"))
158 std::cout << "processing /yp2/routes/route["
159 << route_nr << "]" << std::endl;
161 // process <filter> nodes in third level
162 const xmlNode* node3 = jump_to_children(node2, XML_ELEMENT_NODE);
164 unsigned int filter3_nr = 0;
165 while(node3 && check_element_yp2(node3, "filter"))
169 std::cout << "processing /yp2/routes/route["
170 << route_nr << "]/filter["
171 << filter3_nr << "]" << std::endl;
173 node3 = jump_to_next(node3, XML_ELEMENT_NODE);
176 node2 = jump_to_next(node2, XML_ELEMENT_NODE);
180 void yp2::RouterFleXML::Rep::create_filter(std::string type,
181 const xmlDoc * xmldoc,
184 std::cout << "Created Filter type='" << type
185 << "' id='" << id << "'" << std::endl;
188 yp2::RouterFleXML::Rep::Rep() :
193 yp2::RouterFleXML::RouterFleXML(std::string xmlconf)
198 xmlDocPtr doc = xmlParseMemory(xmlconf.c_str(),
201 throw XMLError("xmlParseMemory failed");
204 m_p->parse_xml_config_dom(doc);
209 yp2::RouterFleXML::~RouterFleXML()
213 const yp2::filter::Base *
214 yp2::RouterFleXML::move(const yp2::filter::Base *filter,
215 const yp2::Package *package) const
224 * indent-tabs-mode: nil
225 * c-file-style: "stroustrup"
227 * vim: shiftwidth=4 tabstop=8 expandtab