__init__.py :  » Ajax » pyjamas » src » examples » infohierarchy » public » services » jsonrpc » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Ajax » pyjamas 
pyjamas » src » examples » infohierarchy » public » services » jsonrpc » __init__.py
"""
  Copyright (c) 2006 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 threading import Event,Lock

from errors import *

from simplejson import JSONDecoder,JSONEncoder
    
    
class JSONRPCEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, JSONRPCError):
            return obj.__class__.__name__
        else:
            return JSONEncoder.default(self, obj)


class Timeout(Exception):
    pass
    
class ResponseEvent:
    """Event which is fired when the response is returned for a request.
    
        For each request sent this event is created. 
        An application can wait for the event to create a blocking request.
    """
    def __init__(self):
        self.__evt = Event()
        
    def waiting(self):
        return not self.__evt.isSet()
        
    def waitForResponse(self, timeOut=None):
        """blocks until the response arrived or timeout is reached."""
        self.__evt.wait(timeOut)
        if self.waiting():
            raise Timeout()
        else:
            if self.response["error"]:
                raise Exception(self.response["error"])
            else:
                return self.response["result"]
        
    def handleResponse(self, resp):
        self.response = resp
        self.__evt.set()
        
        
class SimpleMessageHandler:
    def __init__(self,  DecoderClass=JSONDecoder, EncoderClass=JSONRPCEncoder, messageDelimiter=""):
        self.decoder = DecoderClass()
        self.encoder = EncoderClass()
        self.partialData = ""
        self.respEvents={}
        self.respLock = Lock()
        self.messageDelimiter=messageDelimiter
        
    def close(self):
        pass
        
    def send(self, data):
        pass
        
    def sendMessage(self, msg):
        self.send(self.encoder.encode(msg) + self.messageDelimiter)
    
    def handlePartialData(self, data):
        data = self.partialData + data.replace("\r","").replace("\n", "")
        msgs=[]
        while data != "":
            pos = data.find("{")
            if(pos > -1):
                data=data[pos:]
                try:
                    (obj, pos) = self.decoder.raw_decode(data)
                    data = data[pos:]
                    msgs.append(obj)    
                except:
                    break
            else:
                break
        self.partialData = data
        
        self.handleMessages(msgs)

    def sendNotify(self, name, args):
        """sends a notification object to the peer"""
        self.sendMessage({"method":name, "params": args})
        
    def sendRequest(self, name, args):
        """sends a request to the peer"""
        (respEvt, id) = self.newResponseEvent()
        self.sendMessage({"id":id, "method":name, "params": args})
        return respEvt
        
    def sendResponse(self, id, result, error):
        """sends a response to the peer"""
        self.sendMessage({"result":result, "error": error, "id":id})
    
    def newResponseEvent(self):
        """creates a response event and adds it to a waiting list
           When the reponse arrives it will be removed from the list. 
        """
        respEvt = ResponseEvent()
        self.respLock.acquire()
        eid = id(respEvt)
        self.respEvents[eid] = respEvt
        self.respLock.release()
        return (respEvt,eid)
        
    def handleMessages(self, msgs):
        for msg in msgs:
            if msg.has_key("method") and msg.has_key("params"):
                if msg.has_key("id"):
                    if msg["id"]:
                        self.handleRequest(msg)    
                    else:
                        self.handleNotification(msg)
                else:
                    self.handleNotification(msg)
            elif msg.has_key("result") and msg.has_key("error"):
                self.handleResponse(msg)
            else:#unknown object 
                self.sendResponse(None, InvalidJSONMessage())
                self.close()
                
    def handleResponse(self, resp):
        """handles a response by fireing the response event for the response coming in"""
        id=resp["id"]
        evt = self.respEvents[id]
        del(self.respEvents[id])
        evt.handleResponse(resp)
    
    def handleRequest(self, request):
        pass
    def handleNotification(self, notification):
        pass
        
        
import re
NameAllowedRegExp=re.compile("^[a-zA-Z]\w*$")
def nameAllowed(name):
    """checks if a name is allowed.
    """
    if NameAllowedRegExp.match(name):
        return 1
    else:
        return 0
    
def getMethodByName(obj, name):

    """searches for an object with the name given inside the object given.
       "obj.child.meth" will return the meth obj.
    """
    try:#to get a method by asking the service
        obj = obj._getMethodByName(name)
    except:
        #assumed a childObject is ment 
        #split the name from objName.childObjName... -> [objName, childObjName, ...]
        #and get all objects up to the last in list with name checking from the service object
        names = name.split(".")
        for name in names:
            if nameAllowed(name):
                obj = getattr(obj, name)
            else:
                raise MethodNameNotAllowed()
        
    return obj  
    


class SimpleServiceHandler(SimpleMessageHandler):
    def __init__(self, service, DecoderClass=JSONDecoder, EncoderClass=JSONRPCEncoder, messageDelimiter=""):
        self.service = service
        SimpleMessageHandler.__init__(self, DecoderClass, EncoderClass, messageDelimiter)
        try:
            service._newConnection(self)
        except:
            pass
        
    def close(self):
        try:
            self.service._closingConnection(self)
        except:
            pass
        
    def handleRequest(self, req):
        """handles a request by calling the appropriete method the service exposes"""
        name = req["method"]
        params = req["params"]
        id=req["id"]
        obj=None
        try: #to get a callable obj 
            obj = getMethodByName(self.service, name)
        except MethodNameNotAllowed,e:
            self.sendResponse(id, None, e)
        except:
            self.sendResponse(id, None, MethodNotFound())
        if obj:
            try: #to call the object with parameters
                rslt = obj(*params)
                self.sendResponse(id, rslt, None)
            except TypeError: # wrong arguments
                #todo what if the TypeError was not thrown directly by the callable obj
                s=getTracebackStr()
                self.sendResponse(id, None, InvalidMethodParameters())
            except: #error inside the callable object
                s=getTracebackStr()
                self.sendResponse(id, None, s)
                
    def handleNotification(self, req):
        """handles a notification request by calling the appropriete method the service exposes"""
        name = req["method"]
        params = req["params"]
        try: #to get a callable obj 
            obj = getMethodByName(self.service, name)
            rslt = obj(*params)
        except:
            pass
                
    
    

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.