Log message for revision 39846: Moved more stuff from Five into Zope itself. Event interfaces are now in OFS.interfaces. IFiveObjectClonedEvent has been renamed into IObjectClonedEvent.
Changed: U Zope/branches/philikon-zope32-integration/lib/python/OFS/CopySupport.py U Zope/branches/philikon-zope32-integration/lib/python/OFS/ObjectManager.py U Zope/branches/philikon-zope32-integration/lib/python/OFS/SimpleItem.py A Zope/branches/philikon-zope32-integration/lib/python/OFS/event.py U Zope/branches/philikon-zope32-integration/lib/python/OFS/interfaces.py A Zope/branches/philikon-zope32-integration/lib/python/OFS/subscribers.py U Zope/branches/philikon-zope32-integration/lib/python/Products/BTreeFolder2/BTreeFolder2.py -=- Modified: Zope/branches/philikon-zope32-integration/lib/python/OFS/CopySupport.py =================================================================== --- Zope/branches/philikon-zope32-integration/lib/python/OFS/CopySupport.py 2005-11-02 14:30:36 UTC (rev 39845) +++ Zope/branches/philikon-zope32-integration/lib/python/OFS/CopySupport.py 2005-11-02 14:51:27 UTC (rev 39846) @@ -33,8 +33,9 @@ from zope.event import notify from zope.app.event.objectevent import ObjectCopiedEvent from zope.app.container.contained import ObjectMovedEvent -from Products.Five.event import ObjectWillBeMovedEvent -from Products.Five.event import FiveObjectClonedEvent +from OFS.event import ObjectWillBeMovedEvent +from OFS.event import ObjectClonedEvent +import OFS.subscribers from OFS.interfaces import ICopyContainer from OFS.interfaces import ICopySource @@ -160,12 +161,9 @@ previous call to manage_cutObjects or manage_copyObjects as the first argument. - Also sends IObjectCopiedEvent and IFiveObjectClonedEvent + Also sends IObjectCopiedEvent and IObjectClonedEvent or IObjectWillBeMovedEvent and IObjectMovedEvent. """ - # Done here to avoid circular imports - from Products.Five.subscribers import maybeCallDeprecated - if cb_copy_data is not None: cp = cb_copy_data elif REQUEST is not None and REQUEST.has_key('__cp'): @@ -224,9 +222,9 @@ ob._postCopy(self, op=0) - maybeCallDeprecated('manage_afterClone', ob) + OFS.subscribers.maybeCallDeprecated('manage_afterClone', ob) - notify(FiveObjectClonedEvent(ob)) + notify(ObjectClonedEvent(ob)) if REQUEST is not None: return self.manage_main(self, REQUEST, update_menu=1, @@ -359,9 +357,6 @@ def manage_clone(self, ob, id, REQUEST=None): """Clone an object, creating a new object with the given id. """ - # Done here to avoid circular imports - from Products.Five.subscribers import maybeCallDeprecated - if not ob.cb_isCopyable(): raise CopyError, eNotSupported % escape(ob.getId()) try: @@ -393,9 +388,9 @@ ob._postCopy(self, op=0) - maybeCallDeprecated('manage_afterClone', ob) + OFS.subscribers.maybeCallDeprecated('manage_afterClone', ob) - notify(FiveObjectClonedEvent(ob)) + notify(ObjectClonedEvent(ob)) return ob Modified: Zope/branches/philikon-zope32-integration/lib/python/OFS/ObjectManager.py =================================================================== --- Zope/branches/philikon-zope32-integration/lib/python/OFS/ObjectManager.py 2005-11-02 14:30:36 UTC (rev 39845) +++ Zope/branches/philikon-zope32-integration/lib/python/OFS/ObjectManager.py 2005-11-02 14:51:27 UTC (rev 39846) @@ -46,8 +46,9 @@ from zope.event import notify from zope.app.container.contained import ObjectAddedEvent from zope.app.container.contained import ObjectRemovedEvent -from Products.Five.event import ObjectWillBeAddedEvent -from Products.Five.event import ObjectWillBeRemovedEvent +from OFS.event import ObjectWillBeAddedEvent +from OFS.event import ObjectWillBeRemovedEvent +import OFS.subscribers # the name BadRequestException is relied upon by 3rd-party code @@ -278,9 +279,6 @@ Also sends IObjectWillBeAddedEvent and IObjectAddedEvent. """ - # Done here to avoid circular imports - from Products.Five.subscribers import maybeCallDeprecated - ob = object # better name, keep original function signature v = self._checkId(id) if v is not None: @@ -317,7 +315,7 @@ if not suppress_events: notify(ObjectAddedEvent(ob, self, id)) - maybeCallDeprecated('manage_afterAdd', ob, self) + OFS.subscribers.maybeCallDeprecated('manage_afterAdd', ob, self) return id @@ -334,7 +332,7 @@ # Don't do recursion anymore, a subscriber does that. warnings.warn( "%s.manage_afterClone is deprecated and will be removed in " - "Zope 2.11, you should use an IFiveObjectClonedEvent " + "Zope 2.11, you should use an IObjectClonedEvent " "subscriber instead." % self.__class__.__name__, DeprecationWarning, stacklevel=2) manage_afterClone.__five_method__ = True @@ -353,12 +351,9 @@ Also sends IObjectWillBeRemovedEvent and IObjectRemovedEvent. """ - # Done here to avoid circular imports - from Products.Five.subscribers import maybeCallDeprecated - ob = self._getOb(id) - maybeCallDeprecated('manage_beforeDelete', ob, self) + OFS.subscribers.maybeCallDeprecated('manage_beforeDelete', ob, self) if not suppress_events: notify(ObjectWillBeRemovedEvent(ob, self, id)) Modified: Zope/branches/philikon-zope32-integration/lib/python/OFS/SimpleItem.py =================================================================== --- Zope/branches/philikon-zope32-integration/lib/python/OFS/SimpleItem.py 2005-11-02 14:30:36 UTC (rev 39845) +++ Zope/branches/philikon-zope32-integration/lib/python/OFS/SimpleItem.py 2005-11-02 14:51:27 UTC (rev 39846) @@ -79,7 +79,7 @@ def manage_afterClone(self, item): warnings.warn( "%s.manage_afterClone is deprecated and will be removed in " - "Zope 2.11, you should use an IFiveObjectClonedEvent " + "Zope 2.11, you should use an IObjectClonedEvent " "subscriber instead." % self.__class__.__name__, DeprecationWarning, stacklevel=2) manage_afterClone.__five_method__ = True Added: Zope/branches/philikon-zope32-integration/lib/python/OFS/event.py =================================================================== --- Zope/branches/philikon-zope32-integration/lib/python/OFS/event.py 2005-11-02 14:30:36 UTC (rev 39845) +++ Zope/branches/philikon-zope32-integration/lib/python/OFS/event.py 2005-11-02 14:51:27 UTC (rev 39846) @@ -0,0 +1,62 @@ +############################################################################## +# +# Copyright (c) 2005 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (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. +# +############################################################################## +""" +OFS event definitions. + +$Id$ +""" + +from zope.interface import implements +from zope.app.event.objectevent import ObjectEvent +import OFS.interfaces + + +class ObjectWillBeMovedEvent(ObjectEvent): + """An object will be moved.""" + implements(OFS.interfaces.IObjectWillBeMovedEvent) + + def __init__(self, object, oldParent, oldName, newParent, newName): + ObjectEvent.__init__(self, object) + self.oldParent = oldParent + self.oldName = oldName + self.newParent = newParent + self.newName = newName + +class ObjectWillBeAddedEvent(ObjectWillBeMovedEvent): + """An object will be added to a container.""" + implements(OFS.interfaces.IObjectWillBeAddedEvent) + + def __init__(self, object, newParent=None, newName=None): + #if newParent is None: + # newParent = object.__parent__ + #if newName is None: + # newName = object.__name__ + ObjectWillBeMovedEvent.__init__(self, object, None, None, + newParent, newName) + +class ObjectWillBeRemovedEvent(ObjectWillBeMovedEvent): + """An object will be removed from a container.""" + implements(OFS.interfaces.IObjectWillBeRemovedEvent) + + def __init__(self, object, oldParent=None, oldName=None): + #if oldParent is None: + # oldParent = object.__parent__ + #if oldName is None: + # oldName = object.__name__ + ObjectWillBeMovedEvent.__init__(self, object, oldParent, oldName, + None, None) + +class ObjectClonedEvent(ObjectEvent): + """An object has been cloned into a container.""" + implements(OFS.interfaces.IObjectClonedEvent) Property changes on: Zope/branches/philikon-zope32-integration/lib/python/OFS/event.py ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Modified: Zope/branches/philikon-zope32-integration/lib/python/OFS/interfaces.py =================================================================== --- Zope/branches/philikon-zope32-integration/lib/python/OFS/interfaces.py 2005-11-02 14:30:36 UTC (rev 39845) +++ Zope/branches/philikon-zope32-integration/lib/python/OFS/interfaces.py 2005-11-02 14:51:27 UTC (rev 39846) @@ -894,3 +894,33 @@ """Check the global (zclass) registry for problems, which can be caused by things like disk-based products being deleted. Return true if a problem is found""" + + +################################################## +# Event interfaces + +from zope.app.event.interfaces import IObjectEvent + +class IObjectWillBeMovedEvent(IObjectEvent): + """An object will be moved.""" + oldParent = Attribute("The old location parent for the object.") + oldName = Attribute("The old location name for the object.") + newParent = Attribute("The new location parent for the object.") + newName = Attribute("The new location name for the object.") + +class IObjectWillBeAddedEvent(IObjectWillBeMovedEvent): + """An object will be added to a container.""" + +class IObjectWillBeRemovedEvent(IObjectWillBeMovedEvent): + """An object will be removed from a container""" + +class IObjectClonedEvent(IObjectEvent): + """An object has been cloned (a la Zope 2). + + This is for Zope 2 compatibility, subscribers should really use + IObjectCopiedEvent or IObjectAddedEvent, depending on their use + cases. + + event.object is the copied object, already added to its container. + Note that this event is dispatched to all sublocations. + """ Added: Zope/branches/philikon-zope32-integration/lib/python/OFS/subscribers.py =================================================================== --- Zope/branches/philikon-zope32-integration/lib/python/OFS/subscribers.py 2005-11-02 14:30:36 UTC (rev 39845) +++ Zope/branches/philikon-zope32-integration/lib/python/OFS/subscribers.py 2005-11-02 14:51:27 UTC (rev 39846) @@ -0,0 +1,159 @@ +############################################################################## +# +# Copyright (c) 2005 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (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. +# +############################################################################## +""" +Five subscriber definitions. + +$Id$ +""" + +import warnings +import sys + +from zLOG import LOG, ERROR +from App.config import getConfiguration +from AccessControl import getSecurityManager +from ZODB.POSException import ConflictError +import OFS.interfaces + +from zope.interface import implements +from zope.component import adapts +from zope.app.container.contained import dispatchToSublocations +from zope.app.location.interfaces import ISublocations + + +deprecatedManageAddDeleteClasses = [] + + +def hasDeprecatedMethods(ob): + """Do we need to call the deprecated methods? + """ + for class_ in deprecatedManageAddDeleteClasses: + if isinstance(ob, class_): + return True + return False + +def maybeCallDeprecated(method_name, ob, *args): + """Call a deprecated method, if the framework doesn't call it already. + """ + if hasDeprecatedMethods(ob): + # Already deprecated through zcml + return + method = getattr(ob, method_name) + if getattr(method, '__five_method__', False): + # Method knows it's deprecated + return + if deprecatedManageAddDeleteClasses: + # Not deprecated through zcml and directives fully loaded + class_ = ob.__class__ + warnings.warn( + "Calling %s.%s.%s is deprecated when using Five, " + "instead use event subscribers or " + "mark the class with <five:deprecatedManageAddDelete/>" + % (class_.__module__, class_.__name__, method_name), + DeprecationWarning) + # Note that calling the method can lead to incorrect behavior + # but in the most common case that's better than not calling it. + method(ob, *args) + +################################################## + +class ObjectManagerSublocations(object): + """Get the sublocations for an ObjectManager. + """ + adapts(OFS.interfaces.IObjectManager) + implements(ISublocations) + + def __init__(self, container): + self.container = container + + def sublocations(self): + for ob in self.container.objectValues(): + yield ob + +# The following subscribers should really be defined in ZCML +# but we don't have enough control over subscriber ordering for +# that to work exactly right. +# (Sometimes IItem comes before IObjectManager, sometimes after, +# depending on some of Zope's classes.) +# This code can be simplified when Zope is completely rid of +# manage_afterAdd & co, then IItem wouldn't be relevant anymore and we +# could have a simple subscriber for IObjectManager that directly calls +# dispatchToSublocations. + +def dispatchObjectWillBeMovedEvent(ob, event): + """Multi-subscriber for IItem + IObjectWillBeMovedEvent. + """ + # First, dispatch to sublocations + if OFS.interfaces.IObjectManager.providedBy(ob): + dispatchToSublocations(ob, event) + # Next, do the manage_beforeDelete dance + #import pdb; pdb.set_trace() + if hasDeprecatedMethods(ob): + callManageBeforeDelete(ob, event) + +def dispatchObjectMovedEvent(ob, event): + """Multi-subscriber for IItem + IObjectMovedEvent. + """ + # First, do the manage_afterAdd dance + if hasDeprecatedMethods(ob): + callManageAfterAdd(ob, event) + # Next, dispatch to sublocations + if OFS.interfaces.IObjectManager.providedBy(ob): + dispatchToSublocations(ob, event) + +def dispatchObjectClonedEvent(ob, event): + """Multi-subscriber for IItem + IObjectClonedEvent. + """ + # First, do the manage_afterClone dance + if hasDeprecatedMethods(ob): + callManageAfterClone(ob, event) + # Next, dispatch to sublocations + if OFS.interfaces.IObjectManager.providedBy(ob): + dispatchToSublocations(ob, event) + + +def callManageAfterAdd(ob, event): + """Compatibility subscriber for manage_afterAdd. + """ + container = event.newParent + if container is None: + # this is a remove + return + ob.manage_afterAdd(event.object, container) + +def callManageBeforeDelete(ob, event): + """Compatibility subscriber for manage_beforeDelete. + """ + import OFS.ObjectManager # avoid circular imports + container = event.oldParent + if container is None: + # this is an add + return + try: + ob.manage_beforeDelete(event.object, container) + except OFS.ObjectManager.BeforeDeleteException: + raise + except ConflictError: + raise + except: + LOG('Zope', ERROR, '_delObject() threw', error=sys.exc_info()) + # In debug mode when non-Manager, let exceptions propagate. + if getConfiguration().debug_mode: + if not getSecurityManager().getUser().has_role('Manager'): + raise + +def callManageAfterClone(ob, event): + """Compatibility subscriber for manage_afterClone. + """ + ob.manage_afterClone(event.object) Property changes on: Zope/branches/philikon-zope32-integration/lib/python/OFS/subscribers.py ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/BTreeFolder2/BTreeFolder2.py =================================================================== --- Zope/branches/philikon-zope32-integration/lib/python/Products/BTreeFolder2/BTreeFolder2.py 2005-11-02 14:30:36 UTC (rev 39845) +++ Zope/branches/philikon-zope32-integration/lib/python/Products/BTreeFolder2/BTreeFolder2.py 2005-11-02 14:51:27 UTC (rev 39846) @@ -40,8 +40,9 @@ from zope.event import notify from zope.app.container.contained import ObjectAddedEvent from zope.app.container.contained import ObjectRemovedEvent -from Products.Five.event import ObjectWillBeAddedEvent -from Products.Five.event import ObjectWillBeRemovedEvent +from OFS.event import ObjectWillBeAddedEvent +from OFS.event import ObjectWillBeRemovedEvent +import OFS.subscribers manage_addBTreeFolderForm = DTMLFile('folderAdd', globals()) @@ -411,9 +412,6 @@ def _setObject(self, id, object, roles=None, user=None, set_owner=1, suppress_events=False): - # Done here to avoid circular imports - from Products.Five.subscribers import maybeCallDeprecated - ob = object # better name, keep original function signature v = self._checkId(id) if v is not None: @@ -446,18 +444,15 @@ if not suppress_events: notify(ObjectAddedEvent(ob, self, id)) - maybeCallDeprecated('manage_afterAdd', ob, self) + OFS.subscribers.maybeCallDeprecated('manage_afterAdd', ob, self) return id def _delObject(self, id, dp=1, suppress_events=False): - # Done here to avoid circular imports - from Products.Five.subscribers import maybeCallDeprecated - ob = self._getOb(id) - maybeCallDeprecated('manage_beforeDelete', ob, self) + OFS.subscribers.maybeCallDeprecated('manage_beforeDelete', ob, self) if not suppress_events: notify(ObjectWillBeRemovedEvent(ob, self, id)) _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins