From: <jsl...@us...> - 2003-04-23 05:01:21
|
Update of /cvsroot/webware-sandbox/Sandbox/jslowery/Component In directory sc8-pr-cvs1:/tmp/cvs-serv20740/Component Added Files: Component.py __init__.py Log Message: Initial upload --- NEW FILE: Component.py --- import Queue from WebKit.Page import Page __all__ = ['ComponentType', 'Component', 'ServletComponent', 'CPage'] class ComponentType(type): """ A metatype for components. It handles the behavior of Component classes""" def __new__(cls, name, bases, dict): class_ = type.__new__(cls, name, bases, dict) # Each class maintains a pool of reusable instances. class_._instancePool = Queue.Queue() return class_ def __call__(cls, *args, **kwargs): # We don't always return a new instance, only when the queue is empty. #raise 'ComponentClass.__call__' try: inst = cls._instancePool.get(False) # type.__call__ was call the __new__ __init__ mechanism of the class, # which should be the default or a customized __init__. We need to # call __init__ for the instance again, as it is "fresh" #XXX This should not be the in the try block. What if the __init__ # of the class uses a Queue? inst.__init__(*args, **kwargs) except Queue.Empty: inst = type.__call__(cls, *args, **kwargs) return inst class Component: __metaclass__ = ComponentType def __del__(self): # __del__ is sloppy. only other alternative is making the user explicity # free the object or tying directly into webkit's servlet and putting # the freeing in the sleep() method. # Component instances are not deleted, they are put back in the pool # to be reused. type(self)._instancePool.put(self) class ServletComponent(Component): _actions = [] _servletMethods = [] _handleExceptions = [] def __init__(self, servlet): # Can handle component dependancies here. self._servlet = servlet # Mapping and deleting methods from the component to the servlet # every request can't be the best way? maybe __getattr__ hooks # with per-transaction caching (lazy). # Map servlet methods for s in self._servletMethods: setattr(servlet, s, getattr(self, s)) # Map servlet actions for a in self._actions: setattr(servlet, a, getattr(self, a)) servlet = property(lambda s: s._servlet) def __del__(self): # handled by sleep pass def canHandleException(self, exception): return exception.__class__ in self._handleExceptions # two common hooks def awake(self): pass def sleep(self): # free the object. for s in self._servletMethods: delattr(self.servlet, s) for a in self._actions: delattr(self.servlet, a) self._servlet = None type(self)._instancePool.put(self) class CPage(Page): """ A component-using webkit page. The page can use components and the components can provide delegated functionality or process event hooks (like actions)""" # These components are not to be used directly from the Page's. they provide # functionality that plugs into the instance, accessible from self.attr _components = [] def __init__(self, *args, **kwargs): Page.__init__(self, *args, **kwargs) self._runningComponents = [] self._componentActions = [] def awake(self, *args, **kwargs): Page.awake(self, *args, **kwargs) # get component instances for comClass in self._components: self._runningComponents.append(comClass(self)) for com in self._runningComponents: self._componentActions = self._componentActions + com._actions for com in self._runningComponents: com.awake() def sleep(self, *args, **kwargs): Page.sleep(self, *args, **kwargs) #for c in self._runningComponents: # c.sleep() map(lambda c: c.sleep(), self._runningComponents) self._runningComponents = [] def actions(self): return Page.actions(self) + self._componentActions #def _respond(self, transaction): # # Action hook # req = transaction.request() # for com, actions in self.componentActions().items(): # for action in actions: # if req.hasField('_action_%s' % action) or \ # req.field('_action_', None) == action or \ # (req.hasField('_action_%s.x' % action) and \ # req.hasField('_action_%s.y' % action)): # # apply(getattr(com, action)) # #self.handleAction(action) # return # return Page._respond(self, transaction) def handleException(self, exception): for component in self._runningComponents: if component.canHandleException(exception): return component.handleException(exception) raise exception --- NEW FILE: __init__.py --- from Component import * |