[Zope-Checkins] CVS: Zope3/lib/python/Zope/Event - EventChannel.py:1.2 GlobalEventService.py:1.2 IEvent.py:1.2 IEventChannel.py:1.2 IEventFilter.py:1.2 IEventService.py:1.2 IEventSet.py:1.2 IObjectEvent.py:1.2 ISubscribable.py:1.2 ISubscriber.py:1.2 ISubscriptionAware.py:1.2 Logger.py:1.2 ObjectEvent.py:1.2 Subscribable.py:1.2 __init__.py:1.2 event-meta.zcml:1.2 event.zcml:1.2 metaConfigure.py:1.2
Jim Fulton
jim@zope.com
Mon, 10 Jun 2002 19:29:57 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/Event
In directory cvs.zope.org:/tmp/cvs-serv20468/lib/python/Zope/Event
Added Files:
EventChannel.py GlobalEventService.py IEvent.py
IEventChannel.py IEventFilter.py IEventService.py IEventSet.py
IObjectEvent.py ISubscribable.py ISubscriber.py
ISubscriptionAware.py Logger.py ObjectEvent.py Subscribable.py
__init__.py event-meta.zcml event.zcml metaConfigure.py
Log Message:
Merged Zope-3x-branch into newly forked Zope3 CVS Tree.
=== Zope3/lib/python/Zope/Event/EventChannel.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from Subscribable import Subscribable
+from IEventChannel import IEventChannel
+
+class EventChannel(Subscribable):
+
+ __implements__ = IEventChannel
+
+ def notify(self, event):
+
+ subscriptionses = self._registry.getAllForObject(event)
+
+ for subscriptions in subscriptionses:
+
+ for subscriber,filter in subscriptions:
+ if filter is not None and not filter(event):
+ continue
+ subscriber.notify(event)
+
+
+
+
=== Zope3/lib/python/Zope/Event/GlobalEventService.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from IEventService import IEventService
+from Subscribable import Subscribable
+
+class GlobalEventService(Subscribable):
+
+ __implements__ = IEventService
+
+ def publishEvent(self, event):
+
+ subscriptionses = self._registry.getAllForObject(event)
+
+ for subscriptions in subscriptionses:
+
+ for subscriber,filter in subscriptions:
+ if filter is not None and not filter(event):
+ continue
+ subscriber.notify(event)
+
+
+eventService = GlobalEventService()
+
+
+_clear = eventService._clear
+
+# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
+from Zope.Testing.CleanUp import addCleanUp
+addCleanUp(_clear)
+del addCleanUp
=== Zope3/lib/python/Zope/Event/IEvent.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from Interface import Interface
+
+class IEvent(Interface):
+ """The Base interface for Events"""
=== Zope3/lib/python/Zope/Event/IEventChannel.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from ISubscribable import ISubscribable
+from ISubscriber import ISubscriber
+
+class IEventChannel(ISubscribable, ISubscriber):
+ """Interface for objects which distribute events to subscribers. """
+
+
=== Zope3/lib/python/Zope/Event/IEventFilter.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from Interface import Interface
+
+class IEventFilter(Interface):
+ """Interface for predicates used to filter events."""
+
+ def __call__(event):
+ """Return true if event passes, or false."""
=== Zope3/lib/python/Zope/Event/IEventService.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from ISubscribable import ISubscribable
+
+class IEventService(ISubscribable):
+ """The EventService service is the 'root channel'.
+
+ Its subscribers include other channels.
+
+ It is also the 'default destination' for events
+ when they are generated.
+ """
+
+ def publishEvent(event):
+ """
+ Notify all subscribers of the channel of event.
+
+ Events will often be propagated to higher level IEventServices;
+ This is a policy decision for the IEventService.
+ """
+
+
+
+
=== Zope3/lib/python/Zope/Event/IEventSet.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from Interface import Interface
+
+class IEventSet(ISubscriber):
+ """An unordered collection of location-independent events."""
+
+ def size():
+ """Returns the number of events stored."""
+
+ def get(n=None):
+ """Returns a collection of events.
+
+ This must be iteratable.
+ """
=== Zope3/lib/python/Zope/Event/IObjectEvent.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from IEvent import IEvent
+
+class IObjectEvent(IEvent):
+ """Something has happened to an object.
+
+ The object that generated this event is not necessarily the object
+ refered to by getLocation.
+ """
+
+ def getLocation():
+ """returns the object location."""
+
+class IObjectAddedEvent(IObjectEvent):
+ """An object has been added to a container."""
+
+ def getLocation():
+ """returns the object location after it has been added to the container"""
+
+class IObjectModifiedEvent(IObjectEvent):
+ """An object has been modified"""
+
+class IObjectRemovedEvent(IObjectEvent):
+ """An object has been removed from a container"""
+
+ def getLocation():
+ """location of the object before it was removed"""
+
+ def getObject():
+ """the object that was removed"""
+
+class IObjectMovedEvent(IObjectEvent):
+ """An object has been moved"""
+
+ def getFromLocation():
+ """location of the object before it was moved"""
+
+ def getLocation():
+ """location of the object after it was moved"""
=== Zope3/lib/python/Zope/Event/ISubscribable.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from Interface import Interface
+from IEvent import IEvent
+
+class ISubscribable(Interface):
+ """Objects that broadcast events to subscribers."""
+
+ def subscribe(subscriber, event_type=IEvent, filter=None):
+ """Add subscriber to the list of subscribers for the channel.
+
+ subscriber must implement ISubscriber.
+ Probable subscriber types include the following:
+
+ o Hard Reference (for placeless, global objects and event service)
+
+ Simply register the subscriber directly, in which case, the
+ subscription, and possibly the subscriber, is as persistent as the
+ subscribable. The subscriber will not be wrapped for context
+ or security when called.
+
+ o Soft reference (for placeful, local objects and event service)
+
+ Register an object with a notify method and a path that
+ dereferences the path and delegates notifications.
+
+ o Location-independent reference (for placeful)
+
+ Register an object with a notify method and an ObjectHub ruid that
+ dereferences the ruid via the hub and delegates notifications.
+
+ o Abstract reference (for both)
+
+ Register an object with a notify method and an IReference that
+ dereferences the IReference and delegates notifications.
+
+ event_type, if supplied, is the event interface
+ about which subscriber should be notified, and must implement
+ IEvent. The subscriber will be notified of all events of this
+ event_type and of subclasses of this event_type.
+ The default value, IEvent, as the parent type,
+ is effectively a single catch-all event type that will pass all
+ event types to the subscriber.
+
+ filter, if supplied, must implement IEventFilter; subscriber
+ will be notified of events only if they pass.
+
+ A subscriber may subscribe more than once, even if it has
+ already been subscribed with the same event type and
+ filter. In this case the subscriber will receive multiple
+ calls to its notify method.
+
+ If the subscriber implements ISubscriptionAware, this function
+ will call the subscriber's subscribedTo method.
+ """
+
+ def unsubscribe(subscriber, event_type=None, filter=None):
+ """Unsubscribe subscriber from receiving event types from this
+ subscribable.
+
+ The subscriber is matched via equality (not identity).
+
+ If event_type is None, the default value, the subscriber is
+ unsubscribed completely for all event types from this
+ subscribable (and its parents, if the subscribable is a placeful
+ service). If no subscriptions for this subscriber are
+ present, no error is raised.
+
+ if event_type is supplied, this method will unsubscribe the
+ subscriber from one subscription exactly matching the
+ event_type/filter pair given (the default filter being None).
+ If other subscriptions are present they will remain. If the
+ subscription cannot be found and the subscribable is a placeful
+ service, the unsubscription request is passed to parent
+ services. Raises Zope.Exceptions.NotFound if subscriber wasn't
+ subscribed as expected.
+
+ If the subscriber implements ISubscriptionAware, this function
+ will call the subscriber's unsubscribedFrom method for each
+ individual unsubscribe.
+ """
+
+ def listSubscriptions(subscriber, event_type=None):
+ """returns an iterator of the subscriptions to this channel for
+ the subscriber. if event_type is supplied, the list is limited
+ to that exact event_type. If the subscribable is a placeful
+ service, the list will include subscriptions to parent services.
+ The subscriber is matched via equality (not identity). No
+ subscriptions returns an empty iterator. Each subscription is
+ represented as a tuple (event_type, filter)."""
=== Zope3/lib/python/Zope/Event/ISubscriber.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from Interface import Interface
+
+class ISubscriber(Interface):
+ """Interface for objects which receiving event notifications."""
+
+ def notify(event):
+ """ISubscribables call this method to indicate an event.
+
+ This method must not block!
+
+ This method may raise an exception to veto the event.
+ """
+
+class IIndirectSubscriber(ISubscriber):
+ """Interface for objects that handle subscriptions for another object"""
+
+ def __eq__(other):
+ """this standard python hook allows indirect subscribers to
+ participate in subscribable introspection and unsubscription
+ without being the actual original subscriber object"""
+
+
+
=== Zope3/lib/python/Zope/Event/ISubscriptionAware.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+from Interface import Interface
+
+# these are calls and not events because they are traditional messages
+# between two objects, not events of general interest.
+
+class ISubscriptionAware(Interface):
+
+ def subscribedTo(subscribable, event_type, filter):
+ """alerts the object that it has subscribed, via a call from
+ itself or from another object, to the subscribable. The
+ event_type and filter match the arguments provided to the
+ ISubscribable.subscribe.
+
+ The subscribable must be appropriately placefully wrapped (note
+ that the global event service will have no wrapping)."""
+
+ def unsubscribedFrom(subscribable, event_type, filter):
+ """alerts the object that it has unsubscribed, via a call from
+ itself or from another object, to the subscribable. The
+ event_type and filter match the exact event_type and filter of
+ the deleted subscription, rather than, necessarily, the
+ arguments provided to the ISubscribable.unsubscribe.
+
+ The subscribable must be appropriately placefully wrapped (note
+ that the global event service will have no wrapping)."""
\ No newline at end of file
=== Zope3/lib/python/Zope/Event/Logger.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from ISubscriber import ISubscriber
+from zLOG import LOG,BLATHER
+from pprint import pprint
+from StringIO import StringIO
+
+class Logger:
+
+ __implements__ = ISubscriber
+
+ def __init__(self,severity=BLATHER):
+ self.severity = severity
+
+ def notify(self, event):
+ c = event.__class__
+ detail = StringIO()
+ pprint (event.__dict__,detail)
+ LOG('Event.Logger',
+ self.severity,
+ c.__module__+'.'+c.__name__,
+ detail.getvalue())
+
+
=== Zope3/lib/python/Zope/Event/ObjectEvent.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from IObjectEvent import IObjectAddedEvent, IObjectModifiedEvent
+from IObjectEvent import IObjectRemovedEvent, IObjectMovedEvent
+
+class ObjectAddedEvent:
+ """An object has been added to a container."""
+
+ __implements__ = IObjectAddedEvent
+
+ def __init__(self, location):
+ self.__location = location
+
+ def getLocation(self):
+ """returns the object location after it has been added to the container"""
+ return self.__location
+
+class ObjectModifiedEvent(ObjectAddedEvent):
+ """An object has been modified"""
+
+ __implements__ = IObjectModifiedEvent
+
+class ObjectRemovedEvent:
+ """An object has been removed from a container"""
+
+ __implements__ = IObjectRemovedEvent
+
+
+ def __init__(self, location, obj):
+ self.__location = location
+ self.__obj = obj
+
+ def getLocation(self):
+ """returns the location the object was removed from"""
+ return self.__location
+
+ def getObject(self):
+ """returns the object that was removed."""
+ return self.__obj
+
+
+class ObjectMovedEvent(ObjectAddedEvent):
+ """An object has been moved"""
+
+ __implements__ = IObjectMovedEvent
+
+ def __init__(self, from_location, location):
+ ObjectAddedEvent.__init__(self, location)
+ self.__from_location = from_location
+
+ def getFromLocation(self):
+ """location of the object before it was moved"""
+ return self.__from_location
=== Zope3/lib/python/Zope/Event/Subscribable.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from Zope.ComponentArchitecture.IToIRegistry import TypeRegistry
+from Zope.Exceptions import NotFoundError
+from ISubscribable import ISubscribable
+from ISubscriptionAware import ISubscriptionAware
+from IEvent import IEvent
+from Zope.Proxy.ProxyIntrospection import removeAllProxies
+
+class Subscribable(object): # do we need this to be a type?
+ """a global mix-in"""
+
+ __implements__=ISubscribable
+
+ def __init__(self):
+ self._registry = TypeRegistry()
+ self._subscribers = [] # using an array rather than a dict so
+ # that subscribers may define custom __eq__ methods
+
+ _clear = __init__
+
+ def subscribe(self, subscriber, event_type=IEvent, filter=None):
+
+ clean_subscriber=removeAllProxies(subscriber)
+
+ if ISubscriptionAware.isImplementedBy(subscriber):
+ subscriber.subscribedTo(self, event_type, filter)
+
+ ev_type=event_type
+ if ev_type is IEvent: ev_type=None # optimization
+
+ subscribers = self._registry.getJustForType(ev_type)
+ if subscribers is None:
+ subscribers = []
+ self._registry.register(ev_type, subscribers)
+ subscribers.append((clean_subscriber, filter))
+
+ subs = self._subscribers
+ for sub in subs:
+ if sub[0]==clean_subscriber:
+ sub[1][ev_type]=1
+ break
+ else:
+ subs.append((clean_subscriber,{ev_type:1}))
+
+ self._registry=self._registry #trigger persistence, if pertinent
+
+
+ def unsubscribe(self, subscriber, event_type=None, filter=None):
+
+ clean_subscriber=removeAllProxies(subscriber)
+
+ for subscriber_index in range(len(self._subscribers)):
+ sub=self._subscribers[subscriber_index]
+ if sub[0]==clean_subscriber:
+ ev_set=sub[1]
+ break
+ else:
+ if event_type: raise NotFoundError(subscriber)
+ else: return # this was a generic unsubscribe all request;
+ # work may have been done by a local service
+
+
+ do_alert=ISubscriptionAware.isImplementedBy(clean_subscriber)
+
+ if event_type:
+ ev_type=event_type
+ if event_type is IEvent:
+ ev_type=None # handle optimization
+ if ev_type not in ev_set:
+ raise NotFoundError(subscriber, event_type, filter)
+ subscriptions = self._registry.getJustForType(ev_type)
+ if not subscriptions:
+ raise NotFoundError(subscriber, event_type, filter)
+ try:
+ subscriptions.remove((clean_subscriber, filter))
+ except ValueError:
+ raise NotFoundError(subscriber, event_type, filter)
+ if do_alert:
+ subscriber.unsubscribedFrom(self, event_type, filter)
+ if len(ev_set)==1:
+ for sub in subscriptions:
+ if sub[0]==clean_subscriber:
+ break
+ else:
+ del self._subscribers[subscriber_index]
+ else:
+ for ev_type in ev_set:
+ subscriptions = self._registry.getJustForType(ev_type)
+ subs=subscriptions[:]
+ subscriptions[:] = []
+ for sub in subs:
+ if sub[0] == clean_subscriber: # deleted (not added back)
+ if do_alert:
+ subscriber.unsubscribedFrom(
+ self, ev_type or IEvent, sub[1])
+ # IEvent switch is to make optimization transparent
+ else: # kept (added back)
+ subscriptions.append(sub)
+ del self._subscribers[subscriber_index]
+ self._registry=self._registry #trigger persistence, if pertinent
+
+ def listSubscriptions(self, subscriber, event_type=None):
+
+ subscriber=removeAllProxies(subscriber)
+
+ result=[]
+ if event_type:
+ ev_type=event_type
+ if event_type is IEvent:
+ ev_type=None # handle optimization
+ subscriptions = self._registry.getJustForType(ev_type)
+ if subscriptions:
+ for sub in subscriptions:
+ if sub[0]==subscriber:
+ result.append((event_type, sub[1]))
+ else:
+ for subscriber_index in range(len(self._subscribers)):
+ sub=self._subscribers[subscriber_index]
+ if sub[0]==subscriber:
+ ev_set=sub[1]
+ break
+ else:
+ return result
+ for ev_type in ev_set:
+ subscriptions = self._registry.getJustForType(ev_type)
+ if subscriptions:
+ for sub in subscriptions:
+ if sub[0]==subscriber:
+ result.append((ev_type or IEvent, sub[1]))
+ return result
\ No newline at end of file
=== Zope3/lib/python/Zope/Event/__init__.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from Zope.ComponentArchitecture import getService
+from IEvent import IEvent
+
+
+def getEventService(context):
+ return getService(context, 'Events')
+
+def publishEvent(context, event):
+ return getEventService(context).publishEvent(event)
+
+def subscribe(subscriber, event_type=IEvent, filter=None, context=None):
+ if context is None: context=subscriber
+ return getEventService(context).subscribe(
+ subscriber, event_type, filter)
+
+def subscribeMany(subscriber, event_types=(IEvent,), filter=None, context=None):
+ if context is None: context=subscriber
+ es= getEventService(context).subscribe
+ for event_type in event_types:
+ es(subscriber, event_type, filter)
+
+def unsubscribe(subscriber, event_type=None, filter=None, context=None):
+ if context is None: context=subscriber
+ return getEventService(context).unsubscribe(
+ subscriber, event_type, filter)
+
+def listSubscriptions(subscriber, event_type=None, context=None):
+ if context is None: context=subscriber
+ return getEventService(context).listSubscriptions(
+ subscriber, event_type)
+
+
+
+def _clear():
+ from EventService import _clear; _clear()
=== Zope3/lib/python/Zope/Event/event-meta.zcml 1.1 => 1.2 ===
+
+ <!-- Zope.Event -->
+ <directives namespace="http://namespaces.zope.org/event">
+ <directive name="subscribe" attributes="subscriber event_types filter"
+ handler="Zope.Event.metaConfigure.subscribe" />
+ </directives>
+
+
+</zopeConfigure>
+
+
=== Zope3/lib/python/Zope/Event/event.zcml 1.1 => 1.2 ===
+ xmlns='http://namespaces.zope.org/zope'
+ xmlns:security='http://namespaces.zope.org/security'
+ xmlns:zmi='http://namespaces.zope.org/zmi'
+ xmlns:browser='http://namespaces.zope.org/browser'
+>
+
+<serviceType id='Events'
+ interface='Zope.Event.IEventService.' />
+
+<service serviceType='Events'
+ component='Zope.Event.GlobalEventService.eventService' />
+
+</zopeConfigure>
=== Zope3/lib/python/Zope/Event/metaConfigure.py 1.1 => 1.2 ===
+#
+# 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$
+"""
+
+from Zope.Configuration.Action import Action
+
+from Zope.Event import subscribeMany
+from Zope.Event.IEvent import IEvent
+
+counter = 0
+
+def subscribe(_context, subscriber, event_types=(IEvent,), filter=None):
+ global counter
+ counter += 1
+
+ subscriber = _context.resolve(subscriber)
+
+ event_type_names = event_types
+ event_types=[]
+ for event_type_name in event_type_names.split():
+ event_types.append(_context.resolve(event_type_name))
+
+ if filter is not None:
+ filter = _context.resolve(filter)
+
+ return [
+ Action(
+ # subscriptions can never conflict
+ discriminator = ('subscribe', counter),
+ callable = subscribeMany,
+ args = (subscriber, event_types, filter)
+ )
+ ]