first commit
[bitcoin:spesmilo.git] / jsonrpc / serviceHandler.py
1
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
22 from jsonrpc import loads, dumps, JSONEncodeException
23
24
25 def ServiceMethod(fn):
26     fn.IsServiceMethod = True
27     return fn
28
29 class ServiceException(Exception):
30     pass
31
32 class ServiceRequestNotTranslatable(ServiceException):
33     pass
34
35 class BadServiceRequest(ServiceException):
36     pass
37
38 class ServiceMethodNotFound(ServiceException):
39     def __init__(self, name):
40         self.methodName=name
41
42 class ServiceHandler(object):
43
44     def __init__(self, service):
45         self.service=service
46     
47     def handleRequest(self, json):
48         err=None
49         result = None
50         id_=''
51         
52         try:
53             req = self.translateRequest(json)
54         except ServiceRequestNotTranslatable, e:
55             err = e
56             req={'id':id_}
57
58         if err==None:
59             try:
60                 id_ = req['id']
61                 methName = req['method']
62                 args = req['params']
63             except:
64                 err = BadServiceRequest(json)
65                 
66         if err == None:
67             try:
68                 meth = self.findServiceEndpoint(methName)
69             except Exception, e:
70                 err = e
71
72         if err == None:
73             try:
74                 result = self.invokeServiceEndpoint(meth, args)
75             except Exception, e:
76                 err = e
77
78         resultdata = self.translateResult(result, err, id_)
79
80         return resultdata
81
82     def translateRequest(self, data):
83         try:
84             req = loads(data)
85         except:
86             raise ServiceRequestNotTranslatable(data)
87         return req
88      
89     def findServiceEndpoint(self, name):
90         try:
91             meth = getattr(self.service, name)
92             if getattr(meth, "IsServiceMethod"):
93                 return meth
94             else:
95                 raise ServiceMethodNotFound(name)
96         except AttributeError:
97             raise ServiceMethodNotFound(name)
98
99     def invokeServiceEndpoint(self, meth, args):
100         return meth(*args)
101
102     def translateResult(self, rslt, err, id_):
103         if err != None:
104             err = {"name": err.__class__.__name__, "message":err.message}
105             rslt = None
106
107         try:
108             data = dumps({"result":rslt,"id":id_,"error":err})
109         except JSONEncodeException, e:
110             err = {"name": "JSONEncodeException", "message":"Result Object Not Serializable"}
111             data = dumps({"result":None, "id":id_,"error":err})
112             
113         return data