9e356920d7d109100e520fec0a93a17e3ca60969
[nepi.git] / src / nepi / util / parser / _xml.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 from nepi.core.attributes import Attribute
5 from nepi.util.parser.base import ExperimentData, ExperimentParser
6 from xml.dom import minidom
7
8 class XmlExperimentParser(ExperimentParser):
9     def to_xml(self, experiment_description):
10         data = self.to_data(experiment_description)
11         doc = minidom.Document()        
12         exp_tag = doc.createElement("experiment")
13         testbeds_tag = doc.createElement("testbeds")
14         exp_tag.appendChild(testbeds_tag)
15
16         elements_tags = dict()
17         for guid in data.guids:
18             if data.is_testbed_data(guid):
19                 elements_tag = self.testbed_data_to_xml(doc, testbeds_tag, guid, data)
20                 elements_tags[guid] = elements_tag
21             else:
22                 self.box_data_to_xml(doc, elements_tags, guid, data)
23         doc.appendChild(exp_tag)
24         xml = doc.toprettyxml(indent="    ", encoding="UTF-8")
25         return xml
26
27     def testbed_data_to_xml(self, doc, parent_tag, guid, data):
28         testbed_tag = doc.createElement("testbed") 
29         testbed_tag.setAttribute("guid", str(guid))
30         (testbed_id, testbed_version) = data.get_testbed_data(guid)
31         testbed_tag.setAttribute("testbed_id", str(testbed_id))
32         testbed_tag.setAttribute("testbed_version", str(testbed_version))
33         parent_tag.appendChild(testbed_tag)
34         self.graphical_info_data_to_xml(doc, testbed_tag, guid, data)
35         self.attributes_data_to_xml(doc, testbed_tag, guid, data)
36         elements_tag = doc.createElement("elements")
37         testbed_tag.appendChild(elements_tag)
38         return elements_tag
39
40     def box_data_to_xml(self, doc, elements_tags, guid, data):
41         (testbed_guid, factory_id) = data.get_box_data(guid)
42         element_tag = doc.createElement("element")
43         parent_tag = elements_tags[testbed_guid]
44         parent_tag.appendChild(element_tag)
45         element_tag.setAttribute("factory_id", factory_id)
46         element_tag.setAttribute("guid", str(guid))
47         self.graphical_info_data_to_xml(doc, element_tag, guid, data)
48         self.factory_attributes_data_to_xml(doc, element_tag, guid, data)
49         self.attributes_data_to_xml(doc, element_tag, guid, data)
50         self.traces_data_to_xml(doc, element_tag, guid, data)
51         self.addresses_data_to_xml(doc, element_tag, guid, data)
52         self.routes_data_to_xml(doc, element_tag, guid, data)
53         self.connections_data_to_xml(doc, element_tag, guid, data)
54
55     def graphical_info_data_to_xml(self, doc, parent_tag, guid, data):
56         graphical_info_tag = doc.createElement("graphical_info") 
57         parent_tag.appendChild(graphical_info_tag)
58         (x, y, width, height, label) = data.get_graphical_info_data(guid)
59         graphical_info_tag.setAttribute("x", str(x))
60         graphical_info_tag.setAttribute("y", str(y))
61         graphical_info_tag.setAttribute("width", str(width))
62         graphical_info_tag.setAttribute("height", str(height))
63         graphical_info_tag.setAttribute("label", str(label))
64
65     def factory_attributes_data_to_xml(self, doc, parent_tag, guid, data):
66         factory_attributes_tag = doc.createElement("factory_attributes")
67         for (name, value) in data.get_factory_attribute_data(guid):
68             factory_attribute_tag = doc.createElement("factory_attribute") 
69             factory_attributes_tag.appendChild(factory_attribute_tag)
70             factory_attribute_tag.setAttribute("name", name)
71             factory_attribute_tag.setAttribute("value", str(value))
72             factory_attribute_tag.setAttribute("type", self.type_to_standard(value))
73         if factory_attributes_tag.hasChildNodes():
74             parent_tag.appendChild(factory_attributes_tag)
75
76     def attributes_data_to_xml(self, doc, parent_tag, guid, data):
77         attributes_tag = doc.createElement("attributes") 
78         for name, value in data.get_attribute_data(guid):
79             attribute_tag = doc.createElement("attribute") 
80             attributes_tag.appendChild(attribute_tag)
81             attribute_tag.setAttribute("name", name)
82             attribute_tag.setAttribute("value", str(value))
83             attribute_tag.setAttribute("type", self.type_to_standard(value))
84         if attributes_tag.hasChildNodes():
85             parent_tag.appendChild(attributes_tag)
86
87     def traces_data_to_xml(self, doc, parent_tag, guid, data):
88         traces_tag = doc.createElement("traces") 
89         for name in data.get_trace_data(guid):
90             trace_tag = doc.createElement("trace") 
91             traces_tag.appendChild(trace_tag)
92             trace_tag.setAttribute("name", name)
93         if traces_tag.hasChildNodes():
94             parent_tag.appendChild(traces_tag)
95
96     def addresses_data_to_xml(self, doc, parent_tag, guid, data):
97         addresses_tag = doc.createElement("addresses") 
98         for (autoconfigure, address, family, netprefix, broadcast) \
99                 in data.get_address_data(guid):
100             address_tag = doc.createElement("address") 
101             addresses_tag.appendChild(address_tag)
102             if autoconfigure:
103                 address_tag.setAttribute("AutoConfigure", str(autoconf))
104             if address:
105                 address_tag.setAttribute("Address", str(address))
106             address_tag.setAttribute("Family", str(family))
107             address_tag.setAttribute("NetPrefix", str(netprefix))
108             if broadcast:
109                 address_tag.setAttribute("Broadcast", str(broadcast))
110         if addresses_tag.hasChildNodes():
111             parent_tag.appendChild(addresses_tag)
112
113     def routes_data_to_xml(self, doc, parent_tag, guid, data):
114         routes_tag = doc.createElement("routes") 
115         for (family, destination, netprefix, nexthop) \
116                 in data.get_route_data(guid):
117             route_tag = doc.createElement("route") 
118             routes_tag.appendChild(route_tag)
119             route_tag.setAttribute("Family", str(family))
120             route_tag.setAttribute("Destination", str(destination))
121             route_tag.setAttribute("NetPrefix", str(netprefix))
122             route_tag.setAttribute("NextHop", str(nexthop))
123         if routes_tag.hasChildNodes():
124             parent_tag.appendChild(routes_tag)
125
126     def connections_data_to_xml(self, doc, parent_tag, guid, data):
127         connections_tag = doc.createElement("connections") 
128         for (connector_type_name, other_guid, other_connector_type_name) \
129                 in data.get_connection_data(guid):
130                 connection_tag = doc.createElement("connection") 
131                 connections_tag.appendChild(connection_tag)
132                 connection_tag.setAttribute("connector", connector_type_name)
133                 connection_tag.setAttribute("other_guid", str(other_guid))
134                 connection_tag.setAttribute("other_connector",
135                         other_connector_type_name)
136         if connections_tag.hasChildNodes():
137             parent_tag.appendChild(connections_tag)
138
139     def from_xml_to_data(self, xml):
140         data = ExperimentData()
141         doc = minidom.parseString(xml)
142         testbeds_tag = doc.getElementsByTagName("testbeds")[0] 
143         testbed_tag_list = testbeds_tag.getElementsByTagName("testbed")
144         for testbed_tag in testbed_tag_list:
145             if testbed_tag.nodeType == doc.ELEMENT_NODE:
146                 testbed_guid = int(testbed_tag.getAttribute("guid"))
147                 elements_tag = testbed_tag.getElementsByTagName("elements")[0] 
148                 elements_tag = testbed_tag.removeChild(elements_tag)
149                 self.testbed_data_from_xml(testbed_tag, data)
150                 element_tag_list = elements_tag.getElementsByTagName("element")
151                 for element_tag in element_tag_list:
152                     if element_tag.nodeType == doc.ELEMENT_NODE:
153                         self.box_data_from_xml(element_tag, testbed_guid, data)
154         return data
155
156     def from_xml(self, experiment_description, xml):
157         data = self.from_xml_to_data(xml)
158         self.from_data(experiment_description, data)
159
160     def testbed_data_from_xml(self, tag, data):
161         testbed_guid = int(tag.getAttribute("guid"))
162         testbed_id = str(tag.getAttribute("testbed_id"))
163         testbed_version = str(tag.getAttribute("testbed_version"))
164         data.add_testbed_data(testbed_guid, testbed_id, testbed_version)
165         self.graphical_info_data_from_xml(tag, testbed_guid, data)
166         self.attributes_data_from_xml(tag, testbed_guid, data)
167
168     def box_data_from_xml(self, tag, testbed_guid, data):
169         guid = int(tag.getAttribute("guid"))
170         factory_id = str(tag.getAttribute("factory_id"))
171         data.add_box_data(guid, testbed_guid, factory_id)
172         self.graphical_info_data_from_xml(tag, guid, data)
173         self.factory_attributes_data_from_xml(tag, guid, data)
174         self.attributes_data_from_xml(tag, guid, data)
175         self.traces_data_from_xml(tag, guid, data)
176         self.addresses_data_from_xml(tag, guid, data)
177         self.routes_data_from_xml(tag, guid, data)
178         self.connections_data_from_xml(tag, guid, data)
179
180     def graphical_info_data_from_xml(self, tag, guid, data):
181         graphical_info_tag_list = tag.getElementsByTagName(
182                 "graphical_info")
183         if len(graphical_info_tag_list) == 0:
184             return
185
186         graphical_info_tag = graphical_info_tag_list[0]
187         if graphical_info_tag.nodeType == tag.ELEMENT_NODE:
188             x = float(graphical_info_tag.getAttribute("x"))
189             y = float(graphical_info_tag.getAttribute("y"))
190             width = float(graphical_info_tag.getAttribute("width"))
191             height = float(graphical_info_tag.getAttribute("height"))
192             label = str(graphical_info_tag.getAttribute("label"))
193             data.add_graphical_info_data(guid, x, y, width, height, label)
194
195     def factory_attributes_data_from_xml(self, tag, guid, data):
196         factory_attributes_tag_list = tag.getElementsByTagName(
197                 "factory_attributes")
198         if len(factory_attributes_tag_list) == 0:
199             return
200
201         factory_attribute_tag_list = factory_attributes_tag_list[0].\
202                 getElementsByTagName("factory_attribute")
203         for factory_attribute_tag in factory_attribute_tag_list:
204              if factory_attribute_tag.nodeType == tag.ELEMENT_NODE:
205                 name = str(factory_attribute_tag.getAttribute("name"))
206                 value = factory_attribute_tag.getAttribute("value")
207                 std_type = factory_attribute_tag.getAttribute("type")
208                 value = self.type_from_standard(std_type, value)
209                 data.add_factory_attribute_data(guid, name, value)
210
211     def attributes_data_from_xml(self, tag, guid, data):
212         attributes_tag_list= tag.getElementsByTagName("attributes")
213         if len(attributes_tag_list) == 0:
214             return
215
216         attribute_tag_list = attributes_tag_list[0].\
217                 getElementsByTagName("attribute")
218         for attribute_tag in attribute_tag_list:
219              if attribute_tag.nodeType == tag.ELEMENT_NODE:
220                 name = str(attribute_tag.getAttribute("name"))
221                 value = attribute_tag.getAttribute("value")
222                 std_type = attribute_tag.getAttribute("type")
223                 value = self.type_from_standard(std_type, value)
224                 data.add_attribute_data(guid, name, value)
225
226     def traces_data_from_xml(self, tag, guid, data):
227         traces_tag_list = tag.getElementsByTagName("traces")
228         if len(traces_tag_list) == 0:
229             return
230
231         trace_tag_list = traces_tag_list[0].getElementsByTagName(
232                 "trace")
233         for trace_tag in trace_tag_list:
234              if trace_tag.nodeType == tag.ELEMENT_NODE:
235                 name = str(trace_tag.getAttribute("name"))
236                 data.add_trace_data(guid, name)
237
238     def addresses_data_from_xml(self, tag, guid, data):
239         addresses_tag_list = tag.getElementsByTagName("addresses")
240         if len(addresses_tag_list) == 0:
241             return
242
243         address_tag_list = addresses_tag_list[0].\
244                 getElementsByTagName("address")
245         for address_tag in address_tag_list:
246             if address_tag.nodeType == tag.ELEMENT_NODE:
247                 autoconf = bool(address_tag.getAttribute("AutoConfigure")) \
248                        if address_tag.hasAttribute("AutoConfigure") else None
249                 address = str(address_tag.getAttribute("Address")) \
250                        if address_tag.hasAttribute("Address") else None
251                 family = int(address_tag.getAttribute("Family")) \
252                        if address_tag.hasAttribute("Family") else None
253                 netprefix = int(address_tag.getAttribute("NetPrefix")) \
254                        if address_tag.hasAttribute("NetPrefix") else None
255                 broadcast = str(address_tag.getAttribute("Broadcast")) \
256                        if address_tag.hasAttribute("Broadcast") else None
257                 data.add_address_data(guid, autoconf, address, family, 
258                     netprefix, broadcast)
259
260     def routes_data_from_xml(self, tag, guid, data):
261         routes_tag_list = tag.getElementsByTagName("routes")
262         if len(routes_tag_list) == 0:
263             return
264
265         route_tag_list = routes_tag_list[0].getElementsByTagName("route")
266         for route_tag in route_tag_list:
267             if route_tag.nodeType == tag.ELEMENT_NODE:
268                 family = int(route_tag.getAttribute("Family"))
269                 destination = str(route_tag.getAttribute("Destination"))
270                 netprefix = int(route_tag.getAttribute("NetPrefix"))
271                 nexthop = str(route_tag.getAttribute("NextHop"))
272                 data.add_route_data(guid, family, destination, netprefix, 
273                         nexthop)
274
275     def connections_data_from_xml(self, tag, guid, data):
276         connections_tag_list = tag.getElementsByTagName("connections")
277         if len(connections_tag_list) == 0:
278             return
279
280         connection_tag_list = connections_tag_list[0].getElementsByTagName(
281                 "connection")
282         for connection_tag in connection_tag_list:
283              if connection_tag.nodeType == tag.ELEMENT_NODE:
284                  connector_type_name = str(connection_tag.getAttribute(
285                      "connector"))
286                  other_connector_type_name = str(connection_tag.getAttribute(
287                          "other_connector"))
288                  other_guid = int(connection_tag.getAttribute("other_guid"))
289                  data.add_connection_data(guid, connector_type_name, 
290                          other_guid, other_connector_type_name)
291
292     def type_to_standard(self, value):
293         if type(value) == str:
294             return Attribute.STRING
295         if type(value) == bool:
296             return Attribute.BOOL
297         if type(value) == int:
298             return Attribute.INTEGER
299         if type(value) == float:
300             return Attribute.DOUBLE
301     
302     def type_from_standard(self, type, value):
303         if type == Attribute.STRING:
304             return str(value)
305         if type == Attribute.BOOL:
306             return bool(value)
307         if type == Attribute.INTEGER:
308             return int(value)
309         if type == Attribute.DOUBLE:
310             return float(value)
311