summaryrefslogtreecommitdiffstats
path: root/nova/wsgi.py
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@yahoo.com>2010-09-28 17:08:56 -0700
committerVishvananda Ishaya <vishvananda@yahoo.com>2010-09-28 17:08:56 -0700
commit5d30881d721bdc9e26f71fd2130bd44e7edb1d4d (patch)
tree9ab05a4a982fd447c54bbf9c1a9acb61842de23b /nova/wsgi.py
parentbb1540d7bf2c323d43110738e43e9b99ef49b62c (diff)
parent1540480db44f55dcee8fe1998ed58a306b03f1df (diff)
downloadnova-5d30881d721bdc9e26f71fd2130bd44e7edb1d4d.tar.gz
nova-5d30881d721bdc9e26f71fd2130bd44e7edb1d4d.tar.xz
nova-5d30881d721bdc9e26f71fd2130bd44e7edb1d4d.zip
merged and removed duplicated methods
Diffstat (limited to 'nova/wsgi.py')
-rw-r--r--nova/wsgi.py72
1 files changed, 59 insertions, 13 deletions
diff --git a/nova/wsgi.py b/nova/wsgi.py
index 8a4e2a9f4..da9374542 100644
--- a/nova/wsgi.py
+++ b/nova/wsgi.py
@@ -21,14 +21,17 @@
Utility methods for working with WSGI servers
"""
+import json
import logging
import sys
+from xml.dom import minidom
import eventlet
import eventlet.wsgi
eventlet.patcher.monkey_patch(all=False, socket=True)
import routes
import routes.middleware
+import webob
import webob.dec
import webob.exc
@@ -230,7 +233,7 @@ class Controller(object):
class Serializer(object):
"""
- Serializes a dictionary to a Content Type specified by a WSGI environment.
+ Serializes and deserializes dictionaries to certain MIME types.
"""
def __init__(self, environ, metadata=None):
@@ -239,31 +242,74 @@ class Serializer(object):
'metadata' is an optional dict mapping MIME types to information
needed to serialize a dictionary to that type.
"""
- self.environ = environ
self.metadata = metadata or {}
- self._methods = {
- 'application/json': self._to_json,
- 'application/xml': self._to_xml}
+ req = webob.Request(environ)
+ suffix = req.path_info.split('.')[-1].lower()
+ if suffix == 'json':
+ self.handler = self._to_json
+ elif suffix == 'xml':
+ self.handler = self._to_xml
+ elif 'application/json' in req.accept:
+ self.handler = self._to_json
+ elif 'application/xml' in req.accept:
+ self.handler = self._to_xml
+ else:
+ self.handler = self._to_json # default
def to_content_type(self, data):
"""
- Serialize a dictionary into a string. The format of the string
- will be decided based on the Content Type requested in self.environ:
- by Accept: header, or by URL suffix.
+ Serialize a dictionary into a string.
+
+ The format of the string will be decided based on the Content Type
+ requested in self.environ: by Accept: header, or by URL suffix.
+ """
+ return self.handler(data)
+
+ def deserialize(self, datastring):
+ """
+ Deserialize a string to a dictionary.
+
+ The string must be in the format of a supported MIME type.
"""
- mimetype = 'application/xml'
- # TODO(gundlach): determine mimetype from request
- return self._methods.get(mimetype, repr)(data)
+ datastring = datastring.strip()
+ is_xml = (datastring[0] == '<')
+ if not is_xml:
+ return json.loads(datastring)
+ return self._from_xml(datastring)
+
+ def _from_xml(self, datastring):
+ xmldata = self.metadata.get('application/xml', {})
+ plurals = set(xmldata.get('plurals', {}))
+ node = minidom.parseString(datastring).childNodes[0]
+ return {node.nodeName: self._from_xml_node(node, plurals)}
+
+ def _from_xml_node(self, node, listnames):
+ """
+ Convert a minidom node to a simple Python type.
+
+ listnames is a collection of names of XML nodes whose subnodes should
+ be considered list items.
+ """
+ if len(node.childNodes) == 1 and node.childNodes[0].nodeType == 3:
+ return node.childNodes[0].nodeValue
+ elif node.nodeName in listnames:
+ return [self._from_xml_node(n, listnames) for n in node.childNodes]
+ else:
+ result = dict()
+ for attr in node.attributes.keys():
+ result[attr] = node.attributes[attr].nodeValue
+ for child in node.childNodes:
+ if child.nodeType != node.TEXT_NODE:
+ result[child.nodeName] = self._from_xml_node(child, listnames)
+ return result
def _to_json(self, data):
- import json
return json.dumps(data)
def _to_xml(self, data):
metadata = self.metadata.get('application/xml', {})
# We expect data to contain a single key which is the XML root.
root_key = data.keys()[0]
- from xml.dom import minidom
doc = minidom.Document()
node = self._to_xml_node(doc, metadata, root_key, data[root_key])
return node.toprettyxml(indent=' ')