blob: 1f6036c5c891c3d421c6d51d0a18587d29b07cb3 [file] [log] [blame]
mblighe8819cd2008-02-15 16:48:40 +00001
2"""
3 Copyright (c) 2007 Jan-Klaas Kollhof
4
5 This file is part of jsonrpc.
6
7 jsonrpc is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 This software is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this software; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20"""
21
22import traceback
23
24from frontend.afe.simplejson import decoder, encoder
25
26def customConvertJson(value):
27 """\
28 Recursively process JSON values and do type conversions.
29 -change floats to ints
30 -change unicodes to strs
31 """
32 if isinstance(value, float):
33 return int(value)
34 elif isinstance(value, unicode):
35 return str(value)
36 elif isinstance(value, list):
37 return [customConvertJson(item) for item in value]
38 elif isinstance(value, dict):
39 new_dict = {}
40 for key, val in value.iteritems():
41 new_key = customConvertJson(key)
42 new_val = customConvertJson(val)
43 new_dict[new_key] = new_val
44 return new_dict
45 else:
46 return value
47
48json_encoder = encoder.JSONEncoder()
49json_decoder = decoder.JSONDecoder()
50
51
52def ServiceMethod(fn):
53 fn.IsServiceMethod = True
54 return fn
55
56class ServiceException(Exception):
57 pass
58
59class ServiceRequestNotTranslatable(ServiceException):
60 pass
61
62class BadServiceRequest(ServiceException):
63 pass
64
65class ServiceMethodNotFound(ServiceException):
66 pass
67
68class ServiceHandler(object):
69
70 def __init__(self, service):
71 self.service=service
72
73 def handleRequest(self, json):
74 err=None
75 result = None
76 id_=''
77
78 #print 'Request:', json
79
80 try:
81 req = self.translateRequest(json)
82 except ServiceRequestNotTranslatable, e:
83 err = e
84 req={'id':id_}
85
86 if err==None:
87 try:
88 id_ = req['id']
89 methName = req['method']
90 args = req['params']
91 except:
92 err = BadServiceRequest(json)
93
94 if err == None:
95 try:
96 meth = self.findServiceEndpoint(methName)
97 except Exception, e:
98 traceback.print_exc()
99 err = e
100
101 if err == None:
102 try:
103 result = self.invokeServiceEndpoint(meth, args)
104 except Exception, e:
105 traceback.print_exc()
106 err = e
107 resultdata = self.translateResult(result, err, id_)
108
109 return resultdata
110
111 def translateRequest(self, data):
112 try:
113 req = json_decoder.decode(data)
114 except:
115 raise ServiceRequestNotTranslatable(data)
116 req = customConvertJson(req) # -srh
117 return req
118
119 def findServiceEndpoint(self, name):
120 try:
121 meth = getattr(self.service, name)
122# -srh
123# if getattr(meth, "IsServiceMethod"):
124 return meth
125# else:
126# raise ServiceMethodNotFound(name)
127 except AttributeError:
128 raise ServiceMethodNotFound(name)
129
130 def invokeServiceEndpoint(self, meth, args):
131 return meth(*args)
132
133 def translateResult(self, rslt, err, id_):
134 if err != None:
135 err = {"name": err.__class__.__name__, "message":str(err)}
136 rslt = None
137
138 try:
139 data = json_encoder.encode({"result":rslt,"id":id_,"error":err})
140 except TypeError, e:
141 traceback.print_exc()
142 err = {"name": "JSONEncodeException", "message":"Result Object Not Serializable"}
143 data = json_encoder.encode({"result":None, "id":id_,"error":err})
144
145 return data