# # NEPI, a framework to manage network experiments # Copyright (C) 2013 INRIA # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Author: Alina Quereilhac from nepi.design.box import Box from xml.dom import minidom import sys STRING = "string" BOOL = "bool" INTEGER = "integer" DOUBLE = "float" def xmlencode(s): if isinstance(s, str): rv = s.decode("latin1") elif not isinstance(s, unicode): rv = unicode(s) else: rv = s return rv.replace(u'\x00',u'�') def xmldecode(s): return s.replace(u'�',u'\x00').encode("utf8") def from_type(value): if isinstance(value, str): return STRING if isinstance(value, bool): return BOOL if isinstance(value, int): return INTEGER if isinstance(value, float): return DOUBLE def to_type(type, value): if type == STRING: return str(value) if type == BOOL: return value == "True" if type == INTEGER: return int(value) if type == DOUBLE: return float(value) class XMLParser(object): def to_xml(self, box): doc = minidom.Document() root = doc.createElement("boxes") doc.appendChild(root) traversed = dict() self._traverse_boxes(doc, traversed, box) # Keep the order for guid in sorted(traversed.keys()): bnode = traversed[guid] root.appendChild(bnode) try: xml = doc.toprettyxml(indent=" ", encoding="UTF-8") except: print >>sys.stderr, "Oops: generating XML from %s" % (data,) raise return xml def _traverse_boxes(self, doc, traversed, box): bnode = doc.createElement("box") bnode.setAttribute("guid", xmlencode(box.guid)) bnode.setAttribute("label", xmlencode(box.label)) bnode.setAttribute("x", xmlencode(box.x)) bnode.setAttribute("y", xmlencode(box.y)) bnode.setAttribute("width", xmlencode(box.width)) bnode.setAttribute("height", xmlencode(box.height)) traversed[box.guid] = bnode anode = doc.createElement("attributes") bnode.appendChild(anode) for name in sorted(box.attributes): value = getattr(box.a, name) aanode = doc.createElement("attribute") anode.appendChild(aanode) aanode.setAttribute("name", xmlencode(name)) aanode.setAttribute("value", xmlencode(value)) aanode.setAttribute("type", from_type(value)) tnode = doc.createElement("tags") bnode.appendChild(tnode) for tag in sorted(box.tags): ttnode = doc.createElement("tag") tnode.appendChild(ttnode) ttnode.setAttribute("name", xmlencode(tag)) cnode = doc.createElement("connections") bnode.appendChild(cnode) for b in sorted(box.connections): ccnode = doc.createElement("connection") cnode.appendChild(ccnode) ccnode.setAttribute("guid", xmlencode(b.guid)) if b.guid not in traversed: self._traverse_boxes(doc, traversed, b) def from_xml(self, xml): doc = minidom.parseString(xml) bnode_list = doc.getElementsByTagName("box") boxes = dict() connections = dict() for bnode in bnode_list: if bnode.nodeType == doc.ELEMENT_NODE: guid = int(bnode.getAttribute("guid")) label = xmldecode(bnode.getAttribute("label")) x = float(bnode.getAttribute("x")) y = float(bnode.getAttribute("y")) height = float(bnode.getAttribute("height")) width = float(bnode.getAttribute("width")) box = Box(label=label, guid=guid) boxes[guid] = box anode_list = bnode.getElementsByTagName("attribute") for anode in anode_list: name = xmldecode(anode.getAttribute("name")) value = xmldecode(anode.getAttribute("value")) type = xmldecode(anode.getAttribute("type")) value = to_type(type, value) setattr(box.a, name, value) tnode_list = bnode.getElementsByTagName("tag") for tnode in tnode_list: value = xmldecode(tnode.getAttribute("name")) box.tadd(value) connections[box] = set() cnode_list = bnode.getElementsByTagName("connection") for cnode in cnode_list: guid = int(cnode.getAttribute("guid")) connections[box].add(guid) for box, conns in connections.iteritems(): for guid in conns: b = boxes[guid] box.connect(b) return box