PageRenderTime 34ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/boto-2.5.2/boto/jsonresponse.py

#
Python | 163 lines | 139 code | 3 blank | 21 comment | 0 complexity | 5c20cc832f4698e8a37a9800b7a1899c MD5 | raw file
  1. # Copyright (c) 2010 Mitch Garnaat http://garnaat.org/
  2. # Copyright (c) 2010, Eucalyptus Systems, Inc.
  3. #
  4. # Permission is hereby granted, free of charge, to any person obtaining a
  5. # copy of this software and associated documentation files (the
  6. # "Software"), to deal in the Software without restriction, including
  7. # without limitation the rights to use, copy, modify, merge, publish, dis-
  8. # tribute, sublicense, and/or sell copies of the Software, and to permit
  9. # persons to whom the Software is furnished to do so, subject to the fol-
  10. # lowing conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included
  13. # in all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
  17. # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  18. # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  19. # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. # IN THE SOFTWARE.
  22. import xml.sax
  23. import utils
  24. class XmlHandler(xml.sax.ContentHandler):
  25. def __init__(self, root_node, connection):
  26. self.connection = connection
  27. self.nodes = [('root', root_node)]
  28. self.current_text = ''
  29. def startElement(self, name, attrs):
  30. self.current_text = ''
  31. t = self.nodes[-1][1].startElement(name, attrs, self.connection)
  32. if t != None:
  33. if isinstance(t, tuple):
  34. self.nodes.append(t)
  35. else:
  36. self.nodes.append((name, t))
  37. def endElement(self, name):
  38. self.nodes[-1][1].endElement(name, self.current_text, self.connection)
  39. if self.nodes[-1][0] == name:
  40. self.nodes.pop()
  41. self.current_text = ''
  42. def characters(self, content):
  43. self.current_text += content
  44. def parse(self, s):
  45. xml.sax.parseString(s, self)
  46. class Element(dict):
  47. def __init__(self, connection=None, element_name=None,
  48. stack=None, parent=None, list_marker=('Set',),
  49. item_marker=('member', 'item'),
  50. pythonize_name=False):
  51. dict.__init__(self)
  52. self.connection = connection
  53. self.element_name = element_name
  54. self.list_marker = utils.mklist(list_marker)
  55. self.item_marker = utils.mklist(item_marker)
  56. if stack is None:
  57. self.stack = []
  58. else:
  59. self.stack = stack
  60. self.pythonize_name = pythonize_name
  61. self.parent = parent
  62. def __getattr__(self, key):
  63. if key in self:
  64. return self[key]
  65. for k in self:
  66. e = self[k]
  67. if isinstance(e, Element):
  68. try:
  69. return getattr(e, key)
  70. except AttributeError:
  71. pass
  72. raise AttributeError
  73. def get_name(self, name):
  74. if self.pythonize_name:
  75. name = utils.pythonize_name(name)
  76. return name
  77. def startElement(self, name, attrs, connection):
  78. self.stack.append(name)
  79. for lm in self.list_marker:
  80. if name.endswith(lm):
  81. l = ListElement(self.connection, name, self.list_marker,
  82. self.item_marker, self.pythonize_name)
  83. self[self.get_name(name)] = l
  84. return l
  85. if len(self.stack) > 0:
  86. element_name = self.stack[-1]
  87. e = Element(self.connection, element_name, self.stack, self,
  88. self.list_marker, self.item_marker,
  89. self.pythonize_name)
  90. self[self.get_name(element_name)] = e
  91. return (element_name, e)
  92. else:
  93. return None
  94. def endElement(self, name, value, connection):
  95. if len(self.stack) > 0:
  96. self.stack.pop()
  97. value = value.strip()
  98. if value:
  99. if isinstance(self.parent, Element):
  100. self.parent[self.get_name(name)] = value
  101. elif isinstance(self.parent, ListElement):
  102. self.parent.append(value)
  103. class ListElement(list):
  104. def __init__(self, connection=None, element_name=None,
  105. list_marker=['Set'], item_marker=('member', 'item'),
  106. pythonize_name=False):
  107. list.__init__(self)
  108. self.connection = connection
  109. self.element_name = element_name
  110. self.list_marker = list_marker
  111. self.item_marker = item_marker
  112. self.pythonize_name = pythonize_name
  113. def get_name(self, name):
  114. if self.pythonize_name:
  115. name = utils.pythonize_name(name)
  116. return name
  117. def startElement(self, name, attrs, connection):
  118. for lm in self.list_marker:
  119. if name.endswith(lm):
  120. l = ListElement(self.connection, name,
  121. self.list_marker, self.item_marker,
  122. self.pythonize_name)
  123. setattr(self, self.get_name(name), l)
  124. return l
  125. if name in self.item_marker:
  126. e = Element(self.connection, name, parent=self,
  127. list_marker=self.list_marker,
  128. item_marker=self.item_marker,
  129. pythonize_name=self.pythonize_name)
  130. self.append(e)
  131. return e
  132. else:
  133. return None
  134. def endElement(self, name, value, connection):
  135. if name == self.element_name:
  136. if len(self) > 0:
  137. empty = []
  138. for e in self:
  139. if isinstance(e, Element):
  140. if len(e) == 0:
  141. empty.append(e)
  142. for e in empty:
  143. self.remove(e)
  144. else:
  145. setattr(self, self.get_name(name), value)