Package flumotion :: Package common :: Module xmlwriter
[hide private]

Source Code for Module flumotion.common.xmlwriter

  1  # -*- Mode: Python; -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  """xml serializer and component comparison 
 23  """ 
 24   
 25  from cStringIO import StringIO 
 26  from xml.sax.saxutils import quoteattr 
 27   
 28  __version__ = "$Rev: 7162 $" 
 29   
 30   
31 -class XMLWriter(object):
32
33 - def __init__(self):
34 self._data = StringIO() 35 self._tagStack = [] 36 self._indent = 0 37 self._indentChar = ' ' 38 self._indentUnit = 2
39 40 # Private 41
42 - def _calcAttrsLength(self, attributes, indent):
43 if indent == -1: 44 return -1 45 attrLength = 0 46 for attr, value in attributes: 47 if value is None: 48 raise ValueError( 49 "value for attribute %s cannot be None" % (attr, )) 50 attrLength += 1 + len(attr) + len(quoteattr(value)) 51 return attrLength + indent
52
53 - def _collectAttributes(self, attributes, indent=-1):
54 if not attributes: 55 return '' 56 57 if self._calcAttrsLength(attributes, indent) > 79: 58 indentLen = self._indent + indent 59 else: 60 indentLen = 0 61 first = True 62 attrValue = '' 63 for attr, value in attributes: 64 if indentLen and not first: 65 attrValue += '\n%s' % (self._indentChar * indentLen) 66 if value is None: 67 raise ValueError( 68 "value for attribute %s cannot be None" % (attr, )) 69 attrValue += ' %s=%s' % (attr, quoteattr(value)) 70 if first: 71 first = False 72 return attrValue
73
74 - def _openTag(self, tagName, attributes=None):
75 attrs = self._collectAttributes( 76 attributes, len(tagName) + 1) 77 self.writeLine('<%s%s>' % (tagName, attrs))
78
79 - def _closeTag(self, tagName):
80 self.writeLine('</%s>' % (tagName, ))
81 82 # Public API 83
84 - def getXML(self):
85 """Fetches the xml written by the writer 86 @returns: the xml 87 @rtype: string 88 """ 89 return self._data.getvalue()
90
91 - def writeLine(self, line=''):
92 """Write a line to the xml. 93 This method honors the current indentation. 94 """ 95 self._data.write('%s%s\n' % (self._indentChar * self._indent, line))
96
97 - def writeTag(self, tagName, attributes=None, data=None):
98 """Writes out and closes a tag. Optionally writes data as a child node. 99 @param tagName: name of the tag 100 @param attributes: attributes or None 101 @param data: data or None 102 """ 103 if attributes is None: 104 attributes = [] 105 prefix = '<%s' % (tagName, ) 106 if data is not None: 107 suffix = '>%s</%s>' % (data, tagName) 108 else: 109 suffix = '/>' 110 attrs = self._collectAttributes( 111 attributes, len(prefix) + len(suffix)) 112 self.writeLine(prefix + attrs + suffix)
113
114 - def pushTag(self, tagName, attributes=None):
115 """Push a tag:: 116 - writes the tag and the attributes 117 - increase the indentation for subsequent calls 118 @param tagName: name of the tag to write 119 @type tagName: string 120 @param attributes: attributes to write 121 @type attributes: list of 2 sizes tuples; (name, value) 122 """ 123 self._openTag(tagName, attributes) 124 self._tagStack.append(tagName) 125 self._indent += self._indentUnit
126
127 - def popTag(self):
128 """Decreases the indentation and closes the previously opened tag. 129 @returns: name of the closed tag 130 """ 131 self._indent -= self._indentUnit 132 tagName = self._tagStack.pop() 133 self._closeTag(tagName) 134 return tagName
135 136
137 -def cmpComponentType(aType, bType):
138 """Compare two component types the way they should be written in an xml 139 file. Suitable for using as cmp argument to list.sort() or sorted(). 140 @param aType: first component type 141 @type aType: 142 @param bType: second component type 143 @type bType: 144 @returns: -1, 0 or 1, see L{__builtin__.cmp} 145 """ 146 for suffix in ['-producer', 147 '-converter', 148 '-encoder', 149 '-muxer', 150 '-streamer']: 151 bHasSuffix = bType.endswith(suffix) 152 if aType.endswith(suffix): 153 if bHasSuffix: 154 return cmp(aType, bType) 155 else: 156 return -1 157 elif bHasSuffix: 158 return 1 159 return cmp(aType, bType)
160