db4c0d95bd7bcf5d8e424723cd7628e949f01ea7
[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 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, elem_data in data.iteritems():
18             if "testbed_id" in elem_data:
19                 elements_tag = self.testbed_data_to_xml(doc, testbeds_tag, guid,
20                         elem_data)
21                 elements_tags[guid] = elements_tag
22             else:
23                 testbed_guid = elem_data["testbed_guid"]
24                 elements_tag = elements_tags[testbed_guid]
25                 self.box_data_to_xml(doc, elements_tag, guid, elem_data)
26
27         doc.appendChild(exp_tag)
28         xml = doc.toprettyxml(indent="    ", encoding="UTF-8")
29         return xml
30
31     def testbed_data_to_xml(self, doc, parent_tag, guid, testbed_data):
32         testbed_tag = doc.createElement("testbed") 
33         testbed_tag.setAttribute("guid", str(guid))
34         testbed_tag.setAttribute("testbed_id", str(testbed_data["testbed_id"]))
35         testbed_tag.setAttribute("testbed_version", 
36                 str(testbed_data["testbed_version"]))
37         parent_tag.appendChild(testbed_tag)
38         elements_tag = doc.createElement("elements")
39         testbed_tag.appendChild(elements_tag)
40         return elements_tag
41
42     def box_data_to_xml(self, doc, parent_tag, guid, box_data):
43         element_tag = doc.createElement("element")
44         parent_tag.appendChild(element_tag)
45         element_tag.setAttribute("factory_id", str(box_data["factory_id"]))
46         element_tag.setAttribute("guid", str(guid))
47         if "factory_attributes" in box_data:
48             self.factory_attributes_data_to_xml(doc, element_tag,
49                     box_data["factory_attributes"])
50         if "attributes" in box_data:
51             self.attributes_data_to_xml(doc, element_tag, 
52                     box_data["attributes"])
53         if "traces" in box_data:
54             self.traces_data_to_xml(doc, element_tag, box_data["traces"])
55         if "addresses" in box_data:
56             self.addresses_data_to_xml(doc, element_tag, 
57                     box_data["addresses"])
58         if "routes" in box_data:
59             self.routes_data_to_xml(doc, element_tag, box_data["routes"])
60         if "connections" in box_data:
61             self.connections_data_to_xml(doc, element_tag, 
62                     box_data["connections"])
63         
64     def factory_attributes_data_to_xml(self, doc, parent_tag, data):
65         factory_attributes_tag = doc.createElement("factory_attributes") 
66         parent_tag.appendChild(factory_attributes_tag)
67         for name, value in data.iteritems():
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
74     def attributes_data_to_xml(self, doc, parent_tag, data):
75         attributes_tag = doc.createElement("attributes") 
76         parent_tag.appendChild(attributes_tag)
77         for name, value in data.iteritems():
78             attribute_tag = doc.createElement("attribute") 
79             attributes_tag.appendChild(attribute_tag)
80             attribute_tag.setAttribute("name", name)
81             attribute_tag.setAttribute("value", str(value))
82             attribute_tag.setAttribute("type", self.type_to_standard(value))
83
84     def traces_data_to_xml(self, doc, parent_tag, data):
85         traces_tag = doc.createElement("traces") 
86         parent_tag.appendChild(traces_tag)
87         for name in data:
88             trace_tag = doc.createElement("trace") 
89             traces_tag.appendChild(trace_tag)
90             trace_tag.setAttribute("name", name)
91
92     def addresses_data_to_xml(self, doc, parent_tag, data):
93         addresses_tag = doc.createElement("addresses") 
94         parent_tag.appendChild(addresses_tag)
95         for address in data:
96             address_tag = doc.createElement("address") 
97             addresses_tag.appendChild(address_tag)
98             for name, value in address.iteritems():
99                 address_tag.setAttribute(name, str(value))
100
101     def routes_data_to_xml(self, doc, parent_tag, data):
102         routes_tag = doc.createElement("routes") 
103         parent_tag.appendChild(routes_tag)
104         for route in data:
105             route_tag = doc.createElement("route") 
106             routes_tag.appendChild(route_tag)
107             for name, value in route.iteritems():
108                 route_tag.setAttribute(name, str(value))
109
110     def connections_data_to_xml(self, doc, parent_tag, data):
111         connections_tag = doc.createElement("connections") 
112         parent_tag.appendChild(connections_tag)
113         for connector_type_id, connections in data.iteritems():
114             for other_guid, other_connector_type_id in connections.iteritems():
115                 connection_tag = doc.createElement("connection") 
116                 connections_tag.appendChild(connection_tag)
117                 connection_tag.setAttribute("connector", connector_type_id)
118                 connection_tag.setAttribute("other_guid", str(other_guid))
119                 connection_tag.setAttribute("other_connector",
120                         other_connector_type_id)
121
122     def from_xml(self, experiment_description, xml):
123         data = dict()
124         doc = minidom.parseString(xml)
125         testbeds_tag = doc.getElementsByTagName("testbeds")[0] 
126         testbed_tag_list = testbeds_tag.getElementsByTagName("testbed")
127         for testbed_tag in testbed_tag_list:
128             if testbed_tag.nodeType == doc.ELEMENT_NODE:
129                 testbed_data = self.testbed_data_from_xml(testbed_tag)
130                 testbed_guid = testbed_tag.getAttribute("guid")
131                 data[int(testbed_guid)] = testbed_data
132                 elements_tag = testbed_tag.getElementsByTagName("elements")[0] 
133                 element_tag_list = elements_tag.getElementsByTagName("element")
134                 for element_tag in element_tag_list:
135                     if element_tag.nodeType == doc.ELEMENT_NODE:
136                         box_data = self.box_data_from_xml(testbed_guid, element_tag)
137                         guid = element_tag.getAttribute("guid")
138                         data[int(guid)] = box_data
139         print data
140         self.from_data(experiment_description, data)
141
142     def testbed_data_from_xml(self, tag):
143         testbed_id = tag.getAttribute("testbed_id")
144         testbed_version = tag.getAttribute("testbed_version")
145         return dict({
146             "testbed_id": str(testbed_id), 
147             "testbed_version": str(testbed_version),
148             })
149
150     def box_data_from_xml(self, testbed_guid, tag):
151         factory_id = tag.getAttribute("factory_id")
152         data = dict({
153             "testbed_guid": int(testbed_guid),
154             "factory_id": str(factory_id)
155             })
156         self.factory_attributes_data_from_xml(data, tag)
157         self.attributes_data_from_xml(data, tag)
158         self.traces_data_from_xml(data, tag)
159         self.addresses_data_from_xml(data, tag)
160         self.routes_data_from_xml(data, tag)
161         self.connections_data_from_xml(data, tag)
162         return data
163         
164     def factory_attributes_data_from_xml(self, data, tag):
165         factory_attributes_tag_list = tag.getElementsByTagName(
166                 "factory_attributes")
167         if len(factory_attributes_tag_list) == 0:
168             return
169
170         factory_attribute_tag_list = factory_attributes_tag_list[0].\
171                 getElementsByTagName("factory_attribute")
172         factory_attributes_data = dict()
173         for factory_attribute_tag in factory_attribute_tag_list:
174              if factory_attribute_tag.nodeType == tag.ELEMENT_NODE:
175                 name = factory_attribute_tag.getAttribute("name")
176                 value = factory_attribute_tag.getAttribute("value")
177                 std_type = factory_attribute_tag.getAttribute("type")
178                 value = self.type_from_standard(std_type, value)
179                 factory_attributes_data[str(name)] = value
180         data["factory_attributes"] = factory_attributes_data
181     
182     def attributes_data_from_xml(self, data, tag):
183         attributes_tag_list= tag.getElementsByTagName("attributes")
184         if len(attributes_tag_list) == 0:
185             return
186
187         attribute_tag_list = attributes_tag_list[0].\
188                 getElementsByTagName("attribute")
189         attributes_data = dict()
190         for attribute_tag in attribute_tag_list:
191              if attribute_tag.nodeType == tag.ELEMENT_NODE:
192                 name = attribute_tag.getAttribute("name")
193                 value = attribute_tag.getAttribute("value")
194                 std_type = attribute_tag.getAttribute("type")
195                 value = self.type_from_standard(std_type, value)
196                 attributes_data[str(name)] = value
197         data["attributes"] = attributes_data
198
199     def traces_data_from_xml(self, data, tag):
200         traces_tag_list = tag.getElementsByTagName("traces")
201         if len(traces_tag_list) == 0:
202             return
203
204         trace_tag_list = traces_tag_list[0].getElementsByTagName(
205                 "trace")
206         traces_data = list()
207         for trace_tag in trace_tag_list:
208              if trace_tag.nodeType == tag.ELEMENT_NODE:
209                 name = trace_tag.getAttribute("name")
210                 traces_data.append(name)
211         data["traces"] = traces_data
212
213     def addresses_data_from_xml(self, data, tag):
214         addresses_tag_list = tag.getElementsByTagName("addresses")
215         if len(addresses_tag_list) == 0:
216             return
217
218         address_tag_list = addresses_tag_list[0].\
219                 getElementsByTagName("address")
220         addresses_data = list()
221         address_attributes = dict({"AutoConfigure": Attribute.BOOL, 
222             "Address": Attribute.STRING,
223             "Family": Attribute.INTEGER,
224             "NetPrefix": Attribute.INTEGER,
225             "Broadcast": Attribute.STRING 
226             })
227         for address_tag in address_tag_list:
228             if address_tag.nodeType == tag.ELEMENT_NODE:
229                 address_data = dict()
230                 for attr_name in address_attributes.keys():
231                     if address_tag.hasAttribute(attr_name):
232                         value = address_tag.getAttribute(attr_name)
233                         type = address_attributes[attr_name]
234                         address_data[attr_name] = self.type_from_standard(
235                                 type, value)
236                 addresses_data.append(address_data)
237         data["addresses"] = addresses_data
238
239     def routes_data_from_xml(self, data, tag):
240         routes_tag_list = tag.getElementsByTagName("routes")
241         if len(routes_tag_list) == 0:
242             return
243
244         route_tag_list = routes_tag_list[0].getElementsByTagName("route")
245         routes_data = list()
246         route_attributes = dict({"Family": Attribute.INTEGER,
247             "Destination": Attribute.STRING,
248             "NetPrefix": Attribute.INTEGER,
249             "NextHop": Attribute.STRING,
250             "Interface": Attribute.STRING,
251             })
252         for route_tag in route_tag_list:
253             if address_tag.nodeType == tag.ELEMENT_NODE:
254                 route_data = dict()
255                 for attr_name in route_attributes.keys():
256                     if route_tag.hasAttribute(attr_name):
257                         value = route_tag.getAttribute(attr_name)
258                         type = route_attributes[attr_name]
259                         route_data[attr_name] = self.type_from_standard(
260                                 type, value)
261                 routes_data.append(route_data)
262         data["routes"] = routes_data
263
264     def connections_data_from_xml(self, data, tag):
265         connections_tag_list = tag.getElementsByTagName("connections")
266         if len(connections_tag_list) == 0:
267             return
268
269         connection_tag_list = connections_tag_list[0].getElementsByTagName(
270                 "connection")
271         connections_data = dict()
272         for connection_tag in connection_tag_list:
273              if connection_tag.nodeType == tag.ELEMENT_NODE:
274                  connector = connection_tag.getAttribute("connector")
275                  other_connector = connection_tag.getAttribute(
276                          "other_connector")
277                  other_guid = connection_tag.getAttribute("other_guid")
278                  if not connector in connections_data:
279                      connections_data[str(connector)] = dict()
280                  connection_data = connections_data[str(connector)]
281                  connection_data[int(other_guid)] = str(other_connector)
282         data["connections"] = connections_data
283
284     def type_to_standard(self, value):
285         if type(value) == str:
286             return Attribute.STRING
287         if type(value) == bool:
288             return Attribute.BOOL
289         if type(value) == int:
290             return Attribute.INTEGER
291         if type(value) == float:
292             return Attribute.DOUBLE
293     
294     def type_from_standard(self, type, value):
295         if type == Attribute.STRING:
296             return str(value)
297         if type == Attribute.BOOL:
298             return bool(value)
299         if type == Attribute.INTEGER:
300             return int(value)
301         if type == Attribute.DOUBLE:
302             return float(value)
303