Index: third_party/gsutil/boto/boto/jsonresponse.py |
diff --git a/third_party/gsutil/boto/boto/jsonresponse.py b/third_party/gsutil/boto/boto/jsonresponse.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..01e1f54ff73ecbfc5b31a9f524ac3f2bc07adb11 |
--- /dev/null |
+++ b/third_party/gsutil/boto/boto/jsonresponse.py |
@@ -0,0 +1,163 @@ |
+# Copyright (c) 2010 Mitch Garnaat http://garnaat.org/ |
+# Copyright (c) 2010, Eucalyptus Systems, Inc. |
+# |
+# Permission is hereby granted, free of charge, to any person obtaining a |
+# copy of this software and associated documentation files (the |
+# "Software"), to deal in the Software without restriction, including |
+# without limitation the rights to use, copy, modify, merge, publish, dis- |
+# tribute, sublicense, and/or sell copies of the Software, and to permit |
+# persons to whom the Software is furnished to do so, subject to the fol- |
+# lowing conditions: |
+# |
+# The above copyright notice and this permission notice shall be included |
+# in all copies or substantial portions of the Software. |
+# |
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
+# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
+# IN THE SOFTWARE. |
+ |
+import xml.sax |
+import utils |
+ |
+class XmlHandler(xml.sax.ContentHandler): |
+ |
+ def __init__(self, root_node, connection): |
+ self.connection = connection |
+ self.nodes = [('root', root_node)] |
+ self.current_text = '' |
+ |
+ def startElement(self, name, attrs): |
+ self.current_text = '' |
+ t = self.nodes[-1][1].startElement(name, attrs, self.connection) |
+ if t != None: |
+ if isinstance(t, tuple): |
+ self.nodes.append(t) |
+ else: |
+ self.nodes.append((name, t)) |
+ |
+ def endElement(self, name): |
+ self.nodes[-1][1].endElement(name, self.current_text, self.connection) |
+ if self.nodes[-1][0] == name: |
+ self.nodes.pop() |
+ self.current_text = '' |
+ |
+ def characters(self, content): |
+ self.current_text += content |
+ |
+ def parse(self, s): |
+ xml.sax.parseString(s, self) |
+ |
+class Element(dict): |
+ |
+ def __init__(self, connection=None, element_name=None, |
+ stack=None, parent=None, list_marker=('Set',), |
+ item_marker=('member', 'item'), |
+ pythonize_name=False): |
+ dict.__init__(self) |
+ self.connection = connection |
+ self.element_name = element_name |
+ self.list_marker = utils.mklist(list_marker) |
+ self.item_marker = utils.mklist(item_marker) |
+ if stack is None: |
+ self.stack = [] |
+ else: |
+ self.stack = stack |
+ self.pythonize_name = pythonize_name |
+ self.parent = parent |
+ |
+ def __getattr__(self, key): |
+ if key in self: |
+ return self[key] |
+ for k in self: |
+ e = self[k] |
+ if isinstance(e, Element): |
+ try: |
+ return getattr(e, key) |
+ except AttributeError: |
+ pass |
+ raise AttributeError |
+ |
+ def get_name(self, name): |
+ if self.pythonize_name: |
+ name = utils.pythonize_name(name) |
+ return name |
+ |
+ def startElement(self, name, attrs, connection): |
+ self.stack.append(name) |
+ for lm in self.list_marker: |
+ if name.endswith(lm): |
+ l = ListElement(self.connection, name, self.list_marker, |
+ self.item_marker, self.pythonize_name) |
+ self[self.get_name(name)] = l |
+ return l |
+ if len(self.stack) > 0: |
+ element_name = self.stack[-1] |
+ e = Element(self.connection, element_name, self.stack, self, |
+ self.list_marker, self.item_marker, |
+ self.pythonize_name) |
+ self[self.get_name(element_name)] = e |
+ return (element_name, e) |
+ else: |
+ return None |
+ |
+ def endElement(self, name, value, connection): |
+ if len(self.stack) > 0: |
+ self.stack.pop() |
+ value = value.strip() |
+ if value: |
+ if isinstance(self.parent, Element): |
+ self.parent[self.get_name(name)] = value |
+ elif isinstance(self.parent, ListElement): |
+ self.parent.append(value) |
+ |
+class ListElement(list): |
+ |
+ def __init__(self, connection=None, element_name=None, |
+ list_marker=['Set'], item_marker=('member', 'item'), |
+ pythonize_name=False): |
+ list.__init__(self) |
+ self.connection = connection |
+ self.element_name = element_name |
+ self.list_marker = list_marker |
+ self.item_marker = item_marker |
+ self.pythonize_name = pythonize_name |
+ |
+ def get_name(self, name): |
+ if self.pythonize_name: |
+ name = utils.pythonize_name(name) |
+ return name |
+ |
+ def startElement(self, name, attrs, connection): |
+ for lm in self.list_marker: |
+ if name.endswith(lm): |
+ l = ListElement(self.connection, name, |
+ self.list_marker, self.item_marker, |
+ self.pythonize_name) |
+ setattr(self, self.get_name(name), l) |
+ return l |
+ if name in self.item_marker: |
+ e = Element(self.connection, name, parent=self, |
+ list_marker=self.list_marker, |
+ item_marker=self.item_marker, |
+ pythonize_name=self.pythonize_name) |
+ self.append(e) |
+ return e |
+ else: |
+ return None |
+ |
+ def endElement(self, name, value, connection): |
+ if name == self.element_name: |
+ if len(self) > 0: |
+ empty = [] |
+ for e in self: |
+ if isinstance(e, Element): |
+ if len(e) == 0: |
+ empty.append(e) |
+ for e in empty: |
+ self.remove(e) |
+ else: |
+ setattr(self, self.get_name(name), value) |