summaryrefslogtreecommitdiffstats
path: root/silpa/jsonrpc/serviceHandler.py
blob: 3fb567573163663cb5c3778f4545e2ac1117d6c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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