3a6efaf5005d948b136dab5c4941c26afb0bbad3
[OpenSRF.git] / src / python / osrf / gateway.py
1 from xml.dom import minidom
2 from xml.sax import handler, make_parser, saxutils
3 from json import *
4 from net_obj import *
5 import urllib, urllib2, sys
6
7 defaultHost = None
8
9 class GatewayRequest:
10     def __init__(self, service, method, params=[]):
11         self.service = service
12         self.method = method
13         self.params = params
14
15     def send(self):
16         params = self.buildPOSTParams()
17         request = urllib2.Request(self.buildURL(), data=params)
18         response = None
19         try:
20             response =urllib2.urlopen(request)
21         except urllib2.HTTPError, e:
22             # log this?
23             sys.stderr.write('HTTPError: code=%d : %s' % (e.code, str(e)))
24             raise e
25             
26         return self.handleResponse(response)
27
28     def buildPOSTParams(self):
29
30         params = urllib.urlencode({   
31             'service': self.service,
32             'method': self.method,
33             'format': self.getFormat()
34         })
35
36         for p in self.params:
37             param = {'param': osrfObjectToJSON(p)}
38             params += '&%s' % urllib.urlencode(param)
39
40         return params
41
42     def setDefaultHost(host):
43         global defaultHost
44         defaultHost = host
45     setDefaultHost = staticmethod(setDefaultHost)
46
47     def buildURL(self):
48         return 'http://%s/gateway' % defaultHost
49
50
51 class XMLGatewayRequest(GatewayRequest):
52
53     def __init__(self, service, method, *params):
54         GatewayRequest.__init__(self, service, method, list(params))
55
56     def getFormat(self):
57         return 'xml'
58
59     def handleResponse(self, response):
60         handler = XMLGatewayParser()
61         parser = make_parser()
62         parser.setContentHandler(handler)
63         parser.parse(response)
64         return handler.getResult()
65
66 class XMLGatewayParser(handler.ContentHandler):
67
68     def __init__(self):
69         self.result = None
70         self.objStack = []
71         self.keyStack = []
72
73     def getResult(self):
74         return self.result
75
76     def __getAttr(self, attrs, name):
77         for (k, v) in attrs.items():
78             if k == name:
79                 return v
80         return None
81
82     def startElement(self, name, attrs):
83
84         # XXX add support for serializable objects!
85
86         if name == 'element': # this is an object item wrapper
87             self.keyStack.append(self.__getAttr(attrs, 'key'))
88             return
89
90         if name == 'object':
91             obj = {}
92             self.appendChild(obj)
93             self.objStack.append(obj)
94             return
95
96         if name == 'array':
97             obj = []
98             self.appendChild(obj)
99             self.objStack.append(obj)
100             return
101
102         if name == 'null':
103             self.appendChild(None)
104             return
105
106         if name == 'boolean':
107             self.appendChild((self.__getAttr(attrs, 'value') == 'true'))
108             return
109
110
111     def appendChild(self, child):
112
113         if self.result == None:
114             self.result = child
115
116         if not self.objStack: return;
117
118         parent = self.objStack[len(self.objStack)-1]
119
120         if( isinstance(parent, list) ):
121             parent.append(child)
122         else:
123             parent[self.keyStack.pop()] = child
124
125     def endElement(self, name):
126         if name == 'array' or name == 'object':
127             self.objStack.pop()
128
129     def characters(self, chars):
130         #self.appendChild(''.join(chars[start:leng+start]))
131         self.appendChild(urllib.unquote_plus(chars))
132
133
134
135     
136