[Zope3-dev] Missing ObjectContentModifiedEvent
Uwe Oestermeier
u.oestermeier at iwm-kmrc.de
Wed May 11 05:18:24 EDT 2005
Dieter Maurer wrote:
>As soon as you index the content, you will be interested
>to distinguish between a modification in the primary
>content and some meta data (as it has big repercussions
>on the speed of the reindexing).
I agree, but perhaps we can find a compromise that fits
all needs. I propose to use pluggable modification utilities.
The container related events are already fired by only two
functions (setitem and uncontained). If we introduce a third
one for object modification (e.g. update or modify and an
additional annotate if needed), we can replace these
functions with callable utilities, which are responsible for
performing the changes and firing the events.
It's then up these components which events are
actually used.
Direct calls of ObjectModifiedEvents can then be marked as
deprecated to ensure that all applications will use
these pluggable modifiers.
Regards,
Uwe
The following code should make clear what I mean:
#! python
import doctest, unittest, zope
from zope.app import zapi
from zope.interface import Interface, implements
from zope.app.event.objectevent import ObjectModifiedEvent
from zope.app.event.interfaces import IObjectModifiedEvent
class IPluggableModifier(Interface) :
"""
A pluggable modifier can be used to replace the
existing modification mechanism in Zope.
It should be used in all places where other systems
are notified about changes.
The implementation must ensure that
at least one IObjectModifiedEvent is fired
if an object's state has been changed.
"""
def __call__(self, obj, interface, **kw) :
"""
Performs the update and fires an IObjectModifiedEvent.
It's up to the plugin which specialization of
IObjectModifiedEvent is actually used.
Returns the modified object or None if the object
could not be modified.
"""
class DefaultModifier(object) :
"""
Implements a default behavior that mimics Zope3's current
modification event handling.
Setup :
>>> from zope.component import provideUtility
>>> provideUtility(DefaultModifier(), IPluggableModifier)
>>> events = []
>>> zope.event.subscribers.append(events.append)
>>> class Sample(object) : pass
Usage :
>>> modify = zapi.getUtility(IPluggableModifier)
>>> sample = Sample()
>>> result = modify(sample, None, title='Test',
description='Example')
>>> result == sample
True
>>> IObjectModifiedEvent.providedBy(events[0])
True
>>> sample.title
'Test'
>>> sample.description
'Example'
"""
implements(IPluggableModifier)
def __call__(self, obj, interface, **kw) :
""" Modifies an object and fires an IObjectModifiedEvent. """
if interface is not None :
obj = interface(obj)
for key, value in kw.items() :
setattr(obj, key, value)
zope.event.notify(ObjectModifiedEvent(obj))
return obj
class ValueChangedEvent(object) :
"""
A modification event that keeps additional information about
the used interface, the old and new values.
"""
def __init__(self, object, interface, key, old_value, new_value) :
self.object = object
self.interface = interface
self.key = key
self.old_value = old_value
self.new_value = new_value
class BetterModifier(object) :
"""
Implements a modification behavior that fires more
informative events for more efficient versioning
and reindexing.
Setup :
>>> from zope.component import provideUtility
>>> provideUtility(BetterModifier(), IPluggableModifier)
>>> events = []
>>> zope.event.subscribers.append(events.append)
>>> class Sample(object) : pass
Usage :
>>> modify = zapi.getUtility(IPluggableModifier)
>>> sample = Sample()
>>> result = modify(sample, None, title='Test',
description='Example')
>>> result == sample
True
>>> sample.title
'Test'
>>> sample.description
'Example'
>>> for x in events : print x.__class__.__name__
ValueChangedEvent
ValueChangedEvent
ObjectModifiedEvent
"""
implements(IPluggableModifier)
undefined = object()
def __call__(self, obj, interface, **kw) :
""" Modifies an object and fires an IObjectModifiedEvent. """
if interface is not None :
obj = interface(obj)
for key, value in kw.items() :
old = getattr(obj, key, self.undefined)
if old != value :
setattr(obj, key, value)
event = ValueChangedEvent(obj, interface, key, old, value)
zope.event.notify(event)
zope.event.notify(ObjectModifiedEvent(obj))
return obj
from doctest import DocTestSuite
def test_suite():
return unittest.TestSuite((
DocTestSuite(),
))
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.zope.org/pipermail/zope3-dev/attachments/20050511/836d6c1f/attachment-0001.htm
More information about the Zope3-dev
mailing list