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