diff options
Diffstat (limited to 'silpa/jsonrpc/serviceHandler.py')
-rw-r--r-- | silpa/jsonrpc/serviceHandler.py | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/silpa/jsonrpc/serviceHandler.py b/silpa/jsonrpc/serviceHandler.py new file mode 100644 index 0000000..3fb5675 --- /dev/null +++ b/silpa/jsonrpc/serviceHandler.py @@ -0,0 +1,152 @@ + +""" + Copyright (c) 2007 Jan-Klaas Kollhof + + This file is part of jsonrpc. + + jsonrpc is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This software is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this software; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" + +from common import * +from jsonrpc import JSONEncodeException +from jsonrpc import dumps +from jsonrpc import loads +from utils import * + + +def ServiceMethod(fn): + fn.IsServiceMethod = True + return fn + +class ServiceException(Exception): + pass + +class ServiceRequestNotTranslatable(ServiceException): + pass + +class BadServiceRequest(ServiceException): + pass + +class ServiceMethodNotFound(ServiceException): + def __init__(self, name): + self.methodName = name + +class ServiceHandler(object): + + def __init__(self, service): + self.service = service + + def handleRequest(self, json): + err = None + result = None + id_ = '' + args = None + try: + req = self.translateRequest(json) + except ServiceRequestNotTranslatable, e: + err = e + req = {'id':id_} + + if err == None: + try: + id_ = req['id'] + methName = req['method'] + try: + args = req['params'] + except: + pass + except: + err = BadServiceRequest(json) + module_instance=None + if err == None: + try: + meth = self.locate(methName) + except Exception, e: + err = e + + if err == None: + try: + result = self.call(meth, args) + except Exception, e: + err = e + + resultdata = self.translateResult(result, err, id_) + return resultdata + + def translateRequest(self, data): + try: + req = loads(data) + except: + raise ServiceRequestNotTranslatable(data) + return req + + def locate(self, name): + try: + if name.startswith("system."): + return getattr(self, name.split(".")[1]) + module_manager = ModuleManager() + modules = module_manager.getAllModules() + for module in modules: + for key in dir(module): + try: + method = getattr(module, key) + if getattr(method, "IsServiceMethod"): + if ("modules."+module.__class__.__name__ + "." + key) == name : + meth = method + break + except AttributeError: + pass + if meth==None : + raise ServiceMethodNotFound(name) + except AttributeError: + raise ServiceMethodNotFound(name) + + return meth + def listMethods(self): + results = [] + module_manager = ModuleManager() + modules = module_manager.getAllModules() + for module in modules: + for key in dir(module): + method = getattr(module, key) + try: + if getattr(method, "IsServiceMethod"): + results.append("modules."+module.__class__.__name__ + "." + key) + except: + pass + results.sort() + return results + + def call(self, meth, args=None): + if args == None : + return meth() + else: + return meth(args) #return meth(*args) + + def translateResult(self, rslt, err, id_): + if err != None: + err = {"name": err.__class__.__name__, "message":err.message} + rslt = None + + try: + data = dumps({"result":rslt, "id":id_, "error":err}) + except JSONEncodeException, e: + err = {"name": "JSONEncodeException", "message":"Result Object Not Serializable"} + data = dumps({"result":None, "id":id_, "error":err}) + + return data +# -------------------------------------------------------------------- +# request dispatcher + |