[Zope-Checkins] CVS: Zope3/lib/python/Zope/ObjectHub - IRuidObjectEvent.py:1.1.2.1 RuidObjectEvent.py:1.1.2.1 IObjectHub.py:1.1.2.2 ObjectHub.py:1.1.2.4
Steve Alexander
steve@cat-box.net
Sun, 24 Feb 2002 16:35:39 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/ObjectHub
In directory cvs.zope.org:/tmp/cvs-serv28105
Modified Files:
Tag: Zope-3x-branch
IObjectHub.py ObjectHub.py
Added Files:
Tag: Zope-3x-branch
IRuidObjectEvent.py RuidObjectEvent.py
Log Message:
Added RuidObjectEvents and tests. Updated ObjectHub to act as a persistent EventChannel. Updated tests for ObjectHub to test that it sends out the correct kindsof event for the events it receives. That bit was fun! :-)
=== Added File Zope3/lib/python/Zope/ObjectHub/IRuidObjectEvent.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
Revision information:
$Id: IRuidObjectEvent.py,v 1.1.2.1 2002/02/24 21:35:38 stevea Exp $
"""
from Zope.Event.IEvent import IEvent
class IRuidObjectEvent(IEvent):
"""Something has happened to an object for which there is an ruid.
An ruid is a way or refering to an object independent of location.
"""
def getRuid():
"""Returns the object's ruid."""
def getLocation():
"""Returns the object's current location."""
def getObject():
"""Returns the object."""
class IRuidObjectRegisteredEvent(IRuidObjectEvent):
"""An ruid has been freshly created and mapped against an object."""
class IRuidObjectUnregisteredEvent(IRuidObjectEvent):
"""We are no longer interested in this object."""
class IRuidObjectAddedEvent(IRuidObjectRegisteredEvent):
"""An ruid has been freshly created and mapped against an object.
Also, implies the object has been newly added."""
class IRuidObjectModifiedEvent(IRuidObjectEvent):
"""An object with an ruid has been modified."""
class IRuidObjectContextChangedEvent(IRuidObjectEvent):
"""An object with an ruid has had its context changed. Typically, this
means that it has been moved."""
class IRuidObjectRemovedEvent(IRuidObjectUnregisteredEvent):
"""An object with an ruid has been removed."""
def getLocation():
"""Returns the object's location before it was removed."""
def getObject():
"""Returns the object, or None if the object is unavailable."""
=== Added File Zope3/lib/python/Zope/ObjectHub/RuidObjectEvent.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
Revision information:
$Id: RuidObjectEvent.py,v 1.1.2.1 2002/02/24 21:35:38 stevea Exp $
"""
from IRuidObjectEvent import IRuidObjectRegisteredEvent
from IRuidObjectEvent import IRuidObjectAddedEvent
from IRuidObjectEvent import IRuidObjectUnregisteredEvent
from IRuidObjectEvent import IRuidObjectModifiedEvent
from IRuidObjectEvent import IRuidObjectContextChangedEvent
from IRuidObjectEvent import IRuidObjectRemovedEvent
class RuidObjectEvent:
"""Conenient mix-in for RuidObjectEvents"""
def __init__(self, objecthub, ruid, location):
# we keep all three, to avoid unnecessary lookups
# and to give the objecthub an opportunity to do
# caching of objects
self.__objecthub = objecthub
self.__ruid = ruid
self.__location = location
def getRuid(self):
return self.__ruid
def getLocation(self):
return self.__location
def getObject(self):
if hasattr(self, '_v_object'):
return self._v_object
obj = self._v_object = self.__objecthub.getObject(self.__ruid)
return obj
class RuidObjectRegisteredEvent(RuidObjectEvent):
"""An ruid has been freshly created and mapped against an object."""
__implements__ = IRuidObjectRegisteredEvent
class RuidObjectUnregisteredEvent(RuidObjectEvent):
"""We are no longer interested in this object."""
__implements__ = IRuidObjectUnregisteredEvent
class RuidObjectAddedEvent(RuidObjectEvent):
"""An ruid has been freshly created and mapped against an object.
Also, implies the object has been newly added."""
__implements__ = IRuidObjectAddedEvent
class RuidObjectModifiedEvent(RuidObjectEvent):
"""An object with an ruid has been modified."""
__implements__ = IRuidObjectModifiedEvent
class RuidObjectContextChangedEvent(RuidObjectEvent):
"""An object with an ruid has had its context changed. Typically, this
means that it has been moved."""
__implements__ = IRuidObjectContextChangedEvent
class RuidObjectRemovedEvent(RuidObjectEvent):
"""An object with an ruid has been removed."""
__implements__ = IRuidObjectRemovedEvent
def __init__(self, obj, ruid, location):
self.__object = obj
self.__ruid = ruid
self.__location = location
def getRuid(self):
return self.__ruid
def getLocation(self):
return self.__location
def getObject(self):
return self.__object
=== Zope3/lib/python/Zope/ObjectHub/IObjectHub.py 1.1.2.1 => 1.1.2.2 ===
Table of decisions about maintaining the location<->ruid lookup:
- Add
+ Register
if location already in lookup:
- raise ObjectHubError, as this is not an interesting object
+ raise ObjectHubError, as this is implies bad state somewhere
generate new ruid
place ruid<->location into lookup, to say that we have an
interesting object
- send out ruid object add event to plug-ins, via event channels
+
+ send out ruid object register event to plug-ins, via event channels
+
+ Unregister
+
+ if location not in lookup:
+ raise ObjectHubError, as this is implies bad state somewhere
+ remove location<->ruid from lookup
+
+ send out ruid unregister event to plug-ins, via event channels
+
+ Add (specialises Register)
+
+ as Register, except at the end send out ruid object add event
+ instead
Modify
@@ -69,7 +83,7 @@
send out ruid object context-change event to plug-ins,
via event channels
- Remove
+ Remove (specialises Unregister)
if old_location not in lookup:
ignore this event, as we're not interested in this object
@@ -83,6 +97,10 @@
# XXX: Possibly add Link to EventChannel.
# This implies multiple locations for a ruid.
# We'll refactor later if needed.
+
+ # Possibly also add registerObject and unregisterObject methods
+ # unless these are better handled by events, or unless we don't
+ # need them.
"""
@@ -108,4 +126,10 @@
"""
+ def getObject(ruid):
+ """Returns an object for the given ruid.
+ If there is no such ruid, raise Zope.Exceptions.NotFoundError.
+ If there is no such object, passes through whatever error
+ the traversal service raises.
+ """
=== Zope3/lib/python/Zope/ObjectHub/ObjectHub.py 1.1.2.3 => 1.1.2.4 ===
from Zope.Event.IObjectEvent import IObjectAddedEvent, IObjectModifiedEvent
from Zope.Event.IObjectEvent import IObjectRemovedEvent, IObjectMovedEvent
+from Zope.Event.EventChannel import EventChannel
+from RuidObjectEvent import RuidObjectRegisteredEvent
+from RuidObjectEvent import RuidObjectUnregisteredEvent
+from RuidObjectEvent import RuidObjectAddedEvent
+from RuidObjectEvent import RuidObjectModifiedEvent
+from RuidObjectEvent import RuidObjectContextChangedEvent
+from RuidObjectEvent import RuidObjectRemovedEvent
from Zope.Exceptions import NotFoundError
from Persistence import Persistent
@@ -28,6 +35,9 @@
from Persistence.BTrees.IOBTree import IOBTree
from Persistence.BTrees.OIBTree import OIBTree
+from Zope.App.Traversing.ITraverser import ITraverser
+from Zope.ComponentArchitecture import getAdapter
+
# Code taken from PluginIndexes/common/randid.py
import whrandom
def randid(randint=whrandom.randint, choice=whrandom.choice, signs=(-1,1)):
@@ -43,18 +53,22 @@
def __init__(self):
self.__ruid_to_location = IOBTree()
self.__location_to_ruid = OIBTree()
+ self.__eventchannel = EventChannel()
+ _clear = __init__
+
############################################################
# Implementation methods for interface
# Zope.ObjectHub.IObjectHub
- def subscribe(self, subscriber, event_types=None, filter=None):
+ def subscribe(self, subscriber, event_types=(None,), filter=None):
'''See interface ISubscribable'''
-
+ self.__eventchannel.subscribe(subscriber, event_types, filter)
def unsubscribe(self, subscriber):
'''See interface ISubscribable'''
+ self.__eventchannel.unsubscribe(subscriber)
def notify(self, event):
'''See interface ISubscriber'''
@@ -87,6 +101,12 @@
except KeyError:
raise NotFoundError, ruid
+ def getObject(self, ruid):
+ '''See interface IObjectHub'''
+ location = self.lookupLocation(ruid)
+ adapter = getAdapter(object, ITraverser)
+ return adapter.restrictedTraverse(location)
+
#
############################################################
@@ -117,9 +137,28 @@
canonical_location
ruid = self._generateRuid(canonical_location)
location_to_ruid[canonical_location] = ruid
+
+ # send out to plugins IRuidObjectAddedEvent
+ event = RuidObjectAddedEvent(
+ self,
+ ruid,
+ canonical_location)
+ self.__eventchannel.notify(event)
+
def _objectModified(self, location):
- pass
+ location_to_ruid = self.__location_to_ruid
+ canonical_location = self._canonical(location)
+ if not location_to_ruid.has_key(canonical_location):
+ # we're not interested in this event
+ return
+
+ # send out to plugins IRuidObjectModifiedEvent
+ event = RuidObjectModifiedEvent(
+ self,
+ location_to_ruid[canonical_location],
+ canonical_location)
+ self.__eventchannel.notify(event)
def _objectMoved(self, old_location, new_location):
@@ -138,8 +177,15 @@
del location_to_ruid[canonical_location]
location_to_ruid[canonical_new_location] = ruid
self.__ruid_to_location[ruid] = canonical_new_location
+
+ # send out to plugins IRuidObjectContextChangedEvent
+ event = RuidObjectContextChangedEvent(
+ self,
+ ruid,
+ canonical_new_location)
+ self.__eventchannel.notify(event)
+
-
def _objectRemoved(self, location):
location_to_ruid = self.__location_to_ruid
ruid_to_location = self.__ruid_to_location
@@ -154,4 +200,9 @@
del ruid_to_location[ruid]
del location_to_ruid[canonical_location]
-
+ # send out to plugins IRuidObjectRemovedEvent
+ event = RuidObjectRemovedEvent(
+ None, # no object to give
+ ruid,
+ canonical_location)
+ self.__eventchannel.notify(event)