[Zope-Checkins] SVN: Zope/branches/philikon-zope32-integration/
Zope now sends Zope 3 events when objects are added or removed from
Florent Guillaume
fg at nuxeo.com
Mon Oct 31 15:09:40 EST 2005
Log message for revision 39784:
Zope now sends Zope 3 events when objects are added or removed from
standard containers. manage_afterAdd, manage_beforeDelete and
manage_afterClone are now deprecated. See
lib/python/Products/Five/tests/event.txt for details.
This requires Five 1.3 (included in Zope 2.9).
Changed:
U Zope/branches/philikon-zope32-integration/doc/CHANGES.txt
U Zope/branches/philikon-zope32-integration/lib/python/OFS/Application.py
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/OrderSupport.py
U Zope/branches/philikon-zope32-integration/lib/python/OFS/SimpleItem.py
U Zope/branches/philikon-zope32-integration/lib/python/Products/BTreeFolder2/BTreeFolder2.py
-=-
Modified: Zope/branches/philikon-zope32-integration/doc/CHANGES.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/doc/CHANGES.txt 2005-10-31 20:04:14 UTC (rev 39783)
+++ Zope/branches/philikon-zope32-integration/doc/CHANGES.txt 2005-10-31 20:09:39 UTC (rev 39784)
@@ -26,6 +26,11 @@
Features added
+ - Zope now sends Zope 3 events when objects are added or removed
+ from standard containers. manage_afterAdd, manage_beforeDelete
+ and manage_afterClone are now deprecated. See
+ lib/python/Products/Five/tests/event.txt for details.
+
- Zope now utilizes ZODB 3.6. It had previously used
ZODB 3.4. As a result, the DBTab package was removed, as
ZODB 3.6 has multidatabase support that makes DBTab
Modified: Zope/branches/philikon-zope32-integration/lib/python/OFS/Application.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/OFS/Application.py 2005-10-31 20:04:14 UTC (rev 39783)
+++ Zope/branches/philikon-zope32-integration/lib/python/OFS/Application.py 2005-10-31 20:09:39 UTC (rev 39784)
@@ -459,6 +459,10 @@
from Products.Sessions.BrowserIdManager import BrowserIdManager
bid = BrowserIdManager('browser_id_manager', 'Browser Id Manager')
app._setObject('browser_id_manager', bid)
+ # FIXME explicitely call manage_afterAdd, as sometimes
+ # events are initialized too late
+ browser_id_manager = app.browser_id_manager
+ browser_id_manager.manage_afterAdd(browser_id_manager, app)
app._setInitializerFlag('browser_id_manager')
self.commit('Added browser_id_manager')
@@ -475,6 +479,10 @@
path='/temp_folder/session_data',
requestName='SESSION')
app._setObject('session_data_manager', sdm)
+ # FIXME explicitely call manage_afterAdd, as sometimes
+ # events are initialized too late
+ session_data_manager = app.session_data_manager
+ session_data_manager.manage_afterAdd(session_data_manager, app)
app._setInitializerFlag('session_data_manager')
self.commit('Added session_data_manager')
@@ -523,6 +531,10 @@
from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
error_log = SiteErrorLog()
app._setObject('error_log', error_log)
+ # FIXME explicitely call manage_afterAdd, as sometimes
+ # events are initialized too late
+ error_log = app.error_log
+ error_log.manage_afterAdd(error_log, app)
app._setInitializerFlag('error_log')
self.commit('Added site error_log at /error_log')
Modified: Zope/branches/philikon-zope32-integration/lib/python/OFS/CopySupport.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/OFS/CopySupport.py 2005-10-31 20:04:14 UTC (rev 39783)
+++ Zope/branches/philikon-zope32-integration/lib/python/OFS/CopySupport.py 2005-10-31 20:09:39 UTC (rev 39784)
@@ -30,6 +30,11 @@
from webdav.Lockable import ResourceLockedError
from zExceptions import Unauthorized, BadRequest
from zope.interface import implements
+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.interfaces import ICopyContainer
from OFS.interfaces import ICopySource
@@ -154,85 +159,123 @@
If calling manage_pasteObjects from python code, pass the result of a
previous call to manage_cutObjects or manage_copyObjects as the first
argument.
+
+ Also sends IObjectCopiedEvent and IFiveObjectClonedEvent
+ or IObjectWillBeMovedEvent and IObjectMovedEvent.
"""
- cp=None
+ # Done here to avoid circular imports
+ from Products.Five.subscribers import maybeCallDeprecated
+
if cb_copy_data is not None:
- cp=cb_copy_data
+ cp = cb_copy_data
+ elif REQUEST is not None and REQUEST.has_key('__cp'):
+ cp = REQUEST['__cp']
else:
- if REQUEST and REQUEST.has_key('__cp'):
- cp=REQUEST['__cp']
+ cp = None
if cp is None:
raise CopyError, eNoData
- try: cp=_cb_decode(cp)
- except: raise CopyError, eInvalid
+ try:
+ op, mdatas = _cb_decode(cp)
+ except:
+ raise CopyError, eInvalid
- oblist=[]
- op=cp[0]
+ oblist = []
app = self.getPhysicalRoot()
- result = []
-
- for mdata in cp[1]:
+ for mdata in mdatas:
m = Moniker.loadMoniker(mdata)
- try: ob = m.bind(app)
- except: raise CopyError, eNotFound
+ try:
+ ob = m.bind(app)
+ except ConflictError:
+ raise
+ except:
+ raise CopyError, eNotFound
self._verifyObjectPaste(ob, validate_src=op+1)
oblist.append(ob)
- if op==0:
+ result = []
+ if op == 0:
# Copy operation
for ob in oblist:
+ orig_id = ob.getId()
if not ob.cb_isCopyable():
- raise CopyError, eNotSupported % escape(ob.getId())
- try: ob._notifyOfCopyTo(self, op=0)
- except: raise CopyError, MessageDialog(
- title='Copy Error',
- message=sys.exc_info()[1],
- action ='manage_main')
- ob=ob._getCopy(self)
- orig_id=ob.getId()
- id=self._get_id(ob.getId())
- result.append({'id':orig_id, 'new_id':id})
+ raise CopyError, eNotSupported % escape(orig_id)
+
+ try:
+ ob._notifyOfCopyTo(self, op=0)
+ except ConflictError:
+ raise
+ except:
+ raise CopyError, MessageDialog(
+ title="Copy Error",
+ message=sys.exc_info()[1],
+ action='manage_main')
+
+ id = self._get_id(orig_id)
+ result.append({'id': orig_id, 'new_id': id})
+
+ ob = ob._getCopy(self)
ob._setId(id)
+ notify(ObjectCopiedEvent(ob))
+
self._setObject(id, ob)
ob = self._getOb(id)
- ob._postCopy(self, op=0)
- ob.manage_afterClone(ob)
ob.wl_clearLocks()
+ ob._postCopy(self, op=0)
+
+ maybeCallDeprecated('manage_afterClone', ob)
+
+ notify(FiveObjectClonedEvent(ob))
+
if REQUEST is not None:
return self.manage_main(self, REQUEST, update_menu=1,
cb_dataValid=1)
- if op==1:
+ elif op == 1:
# Move operation
for ob in oblist:
- id=ob.getId()
+ orig_id = ob.getId()
if not ob.cb_isMoveable():
- raise CopyError, eNotSupported % escape(id)
- try: ob._notifyOfCopyTo(self, op=1)
- except: raise CopyError, MessageDialog(
- title='Move Error',
- message=sys.exc_info()[1],
- action ='manage_main')
+ raise CopyError, eNotSupported % escape(orig_id)
+
+ try:
+ ob._notifyOfCopyTo(self, op=1)
+ except ConflictError:
+ raise
+ except:
+ raise CopyError, MessageDialog(
+ title="Move Error",
+ message=sys.exc_info()[1],
+ action='manage_main')
+
if not sanity_check(self, ob):
- raise CopyError, 'This object cannot be pasted into itself'
+ raise CopyError, "This object cannot be pasted into itself"
+ orig_container = aq_parent(aq_inner(ob))
+ if aq_base(orig_container) is aq_base(self):
+ id = orig_id
+ else:
+ id = self._get_id(orig_id)
+ result.append({'id': orig_id, 'new_id': id})
+
+ notify(ObjectWillBeMovedEvent(ob, orig_container, orig_id,
+ self, id))
+
# try to make ownership explicit so that it gets carried
# along to the new location if needed.
ob.manage_changeOwnershipType(explicit=1)
- aq_parent(aq_inner(ob))._delObject(id)
+ orig_container._delObject(orig_id, suppress_events=True)
ob = aq_base(ob)
- orig_id=id
- id=self._get_id(id)
- result.append({'id':orig_id, 'new_id':id })
+ ob._setId(id)
- ob._setId(id)
- self._setObject(id, ob, set_owner=0)
- ob=self._getOb(id)
+ self._setObject(id, ob, set_owner=0, suppress_events=True)
+ ob = self._getOb(id)
+
+ notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id))
+
ob._postCopy(self, op=1)
-
# try to make ownership implicit if possible
ob.manage_changeOwnershipType(explicit=0)
@@ -243,6 +286,7 @@
REQUEST['__cp'] = None
return self.manage_main(self, REQUEST, update_menu=1,
cb_dataValid=0)
+
return result
manage_renameForm=Globals.DTMLFile('dtml/renameForm', globals())
@@ -259,31 +303,48 @@
return None
def manage_renameObject(self, id, new_id, REQUEST=None):
- """Rename a particular sub-object"""
- try: self._checkId(new_id)
- except: raise CopyError, MessageDialog(
- title='Invalid Id',
- message=sys.exc_info()[1],
- action ='manage_main')
- ob=self._getOb(id)
+ """Rename a particular sub-object.
+ """
+ try:
+ self._checkId(new_id)
+ except:
+ raise CopyError, MessageDialog(
+ title='Invalid Id',
+ message=sys.exc_info()[1],
+ action ='manage_main')
+
+ ob = self._getOb(id)
+
if ob.wl_isLocked():
- raise ResourceLockedError, 'Object "%s" is locked via WebDAV' % ob.getId()
+ raise ResourceLockedError, ('Object "%s" is locked via WebDAV'
+ % ob.getId())
if not ob.cb_isMoveable():
raise CopyError, eNotSupported % escape(id)
self._verifyObjectPaste(ob)
- try: ob._notifyOfCopyTo(self, op=1)
- except: raise CopyError, MessageDialog(
- title='Rename Error',
- message=sys.exc_info()[1],
- action ='manage_main')
- self._delObject(id)
+
+ try:
+ ob._notifyOfCopyTo(self, op=1)
+ except ConflictError:
+ raise
+ except:
+ raise CopyError, MessageDialog(
+ title="Rename Error",
+ message=sys.exc_info()[1],
+ action ='manage_main')
+
+ notify(ObjectWillBeMovedEvent(ob, self, id, self, new_id))
+
+ self._delObject(id, suppress_events=True)
ob = aq_base(ob)
ob._setId(new_id)
# Note - because a rename always keeps the same context, we
# can just leave the ownership info unchanged.
- self._setObject(new_id, ob, set_owner=0)
+ self._setObject(new_id, ob, set_owner=0, suppress_events=True)
ob = self._getOb(new_id)
+
+ notify(ObjectMovedEvent(ob, self, id, self, new_id))
+
ob._postCopy(self, op=1)
if REQUEST is not None:
@@ -296,26 +357,46 @@
# Because it's still a "management" function.
manage_clone__roles__=None
def manage_clone(self, ob, id, REQUEST=None):
- # Clone an object, creating a new object with the given id.
+ """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: self._checkId(id)
- except: raise CopyError, MessageDialog(
- title='Invalid Id',
- message=sys.exc_info()[1],
- action ='manage_main')
+ try:
+ self._checkId(id)
+ except:
+ raise CopyError, MessageDialog(
+ title='Invalid Id',
+ message=sys.exc_info()[1],
+ action ='manage_main')
+
self._verifyObjectPaste(ob)
- try: ob._notifyOfCopyTo(self, op=0)
- except: raise CopyError, MessageDialog(
- title='Clone Error',
- message=sys.exc_info()[1],
- action ='manage_main')
- ob=ob._getCopy(self)
+
+ try:
+ ob._notifyOfCopyTo(self, op=0)
+ except ConflictError:
+ raise
+ except:
+ raise CopyError, MessageDialog(
+ title="Clone Error",
+ message=sys.exc_info()[1],
+ action='manage_main')
+
+ ob = ob._getCopy(self)
ob._setId(id)
+ notify(ObjectCopiedEvent(ob))
+
self._setObject(id, ob)
- ob=self._getOb(id)
+ ob = self._getOb(id)
+
ob._postCopy(self, op=0)
- ob.manage_afterClone(ob)
+
+ maybeCallDeprecated('manage_afterClone', ob)
+
+ notify(FiveObjectClonedEvent(ob))
+
return ob
def cb_dataValid(self):
Modified: Zope/branches/philikon-zope32-integration/lib/python/OFS/ObjectManager.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/OFS/ObjectManager.py 2005-10-31 20:04:14 UTC (rev 39783)
+++ Zope/branches/philikon-zope32-integration/lib/python/OFS/ObjectManager.py 2005-10-31 20:09:39 UTC (rev 39784)
@@ -15,6 +15,7 @@
$Id$
"""
+import warnings
import marshal
import sys, fnmatch, copy, os, re
from cgi import escape
@@ -42,6 +43,11 @@
import CopySupport
from interfaces import IObjectManager
from Traversable import Traversable
+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
# the name BadRequestException is relied upon by 3rd-party code
@@ -266,90 +272,99 @@
raise AttributeError, id
return default
- def _setObject(self, id, object, roles=None, user=None, set_owner=1):
- v=self._checkId(id)
- if v is not None: id=v
- try: t=object.meta_type
- except: t=None
+ def _setObject(self, id, object, roles=None, user=None, set_owner=1,
+ suppress_events=False):
+ """Set an object into this container.
+ 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:
+ id = v
+ t = getattr(ob, 'meta_type', None)
+
# If an object by the given id already exists, remove it.
for object_info in self._objects:
if object_info['id'] == id:
self._delObject(id)
break
- self._objects=self._objects+({'id':id,'meta_type':t},)
- self._setOb(id,object)
- object=self._getOb(id)
+ if not suppress_events:
+ notify(ObjectWillBeAddedEvent(ob, self, id))
+ self._objects = self._objects + ({'id': id, 'meta_type': t},)
+ self._setOb(id, ob)
+ ob = self._getOb(id)
+
if set_owner:
- object.manage_fixupOwnershipAfterAdd()
+ # TODO: eventify manage_fixupOwnershipAfterAdd
+ # This will be called for a copy/clone, or a normal _setObject.
+ ob.manage_fixupOwnershipAfterAdd()
# Try to give user the local role "Owner", but only if
# no local roles have been set on the object yet.
- if hasattr(object, '__ac_local_roles__'):
- if object.__ac_local_roles__ is None:
- user=getSecurityManager().getUser()
- if user is not None:
- userid=user.getId()
- if userid is not None:
- object.manage_setLocalRoles(userid, ['Owner'])
+ if getattr(ob, '__ac_local_roles__', _marker) is None:
+ user = getSecurityManager().getUser()
+ if user is not None:
+ userid = user.getId()
+ if userid is not None:
+ ob.manage_setLocalRoles(userid, ['Owner'])
- object.manage_afterAdd(object, self)
+ if not suppress_events:
+ notify(ObjectAddedEvent(ob, self, id))
+
+ maybeCallDeprecated('manage_afterAdd', ob, self)
+
return id
def manage_afterAdd(self, item, container):
- for object in self.objectValues():
- try: s=object._p_changed
- except: s=0
- if hasattr(aq_base(object), 'manage_afterAdd'):
- object.manage_afterAdd(item, container)
- if s is None: object._p_deactivate()
+ # Don't do recursion anymore, a subscriber does that.
+ warnings.warn(
+ "%s.manage_afterAdd is deprecated and will be removed in "
+ "Zope 2.11, you should use an IObjectAddedEvent "
+ "subscriber instead." % self.__class__.__name__,
+ DeprecationWarning, stacklevel=2)
+ manage_afterAdd.__five_method__ = True
def manage_afterClone(self, item):
- for object in self.objectValues():
- try: s=object._p_changed
- except: s=0
- if hasattr(aq_base(object), 'manage_afterClone'):
- object.manage_afterClone(item)
- if s is None: object._p_deactivate()
+ # 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 "
+ "subscriber instead." % self.__class__.__name__,
+ DeprecationWarning, stacklevel=2)
+ manage_afterClone.__five_method__ = True
def manage_beforeDelete(self, item, container):
- for object in self.objectValues():
- try: s=object._p_changed
- except: s=0
- try:
- if hasattr(aq_base(object), 'manage_beforeDelete'):
- object.manage_beforeDelete(item, container)
- except BeforeDeleteException, ob:
- raise
- except ConflictError:
- raise
- except:
- LOG('Zope',ERROR,'manage_beforeDelete() 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
- if s is None: object._p_deactivate()
+ # Don't do recursion anymore, a subscriber does that.
+ warnings.warn(
+ "%s.manage_beforeDelete is deprecated and will be removed in "
+ "Zope 2.11, you should use an IObjectWillBeRemovedEvent "
+ "subscriber instead." % self.__class__.__name__,
+ DeprecationWarning, stacklevel=2)
+ manage_beforeDelete.__five_method__ = True
- def _delObject(self, id, dp=1):
- object=self._getOb(id)
- try:
- object.manage_beforeDelete(object, self)
- except BeforeDeleteException, ob:
- 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
- self._objects=tuple(filter(lambda i,n=id: i['id']!=n, self._objects))
+ def _delObject(self, id, dp=1, suppress_events=False):
+ """Delete an object from this container.
+
+ 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)
+
+ if not suppress_events:
+ notify(ObjectWillBeRemovedEvent(ob, self, id))
+
+ self._objects = tuple([i for i in self._objects
+ if i['id'] != id])
self._delOb(id)
# Indicate to the object that it has been deleted. This is
@@ -357,9 +372,14 @@
# tolerate failure here because the object being deleted could
# be a Broken object, and it is not possible to set attributes
# on Broken objects.
- try: object._v__object_deleted__ = 1
- except: pass
+ try:
+ ob._v__object_deleted__ = 1
+ except:
+ pass
+ if not suppress_events:
+ notify(ObjectRemovedEvent(ob, self, id))
+
def objectIds(self, spec=None):
# Returns a list of subobject ids of the current object.
# If 'spec' is specified, returns objects whose meta_type
Modified: Zope/branches/philikon-zope32-integration/lib/python/OFS/OrderSupport.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/OFS/OrderSupport.py 2005-10-31 20:04:14 UTC (rev 39783)
+++ Zope/branches/philikon-zope32-integration/lib/python/OFS/OrderSupport.py 2005-10-31 20:09:39 UTC (rev 39784)
@@ -30,7 +30,7 @@
from ObjectManager import ObjectManager
-class OrderSupport:
+class OrderSupport(object):
""" Ordered container mixin class.
@@ -251,13 +251,12 @@
# Override Inherited Method of ObjectManager Subclass
#
- _old_manage_renameObject = ObjectManager.inheritedAttribute(
- 'manage_renameObject')
def manage_renameObject(self, id, new_id, REQUEST=None):
""" Rename a particular sub-object without changing its position.
"""
old_position = self.getObjectPosition(id)
- result = self._old_manage_renameObject(id, new_id, REQUEST)
+ result = super(OrderSupport, self).manage_renameObject(id, new_id,
+ REQUEST)
self.moveObjectToPosition(new_id, old_position)
return result
Modified: Zope/branches/philikon-zope32-integration/lib/python/OFS/SimpleItem.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/OFS/SimpleItem.py 2005-10-31 20:04:14 UTC (rev 39783)
+++ Zope/branches/philikon-zope32-integration/lib/python/OFS/SimpleItem.py 2005-10-31 20:09:39 UTC (rev 39784)
@@ -20,6 +20,7 @@
$Id$
"""
+import warnings
import marshal, re, sys, time
import AccessControl.Role, AccessControl.Owned, App.Common
@@ -60,13 +61,28 @@
isTopLevelPrincipiaApplicationObject=0
def manage_afterAdd(self, item, container):
- pass
+ warnings.warn(
+ "%s.manage_afterAdd is deprecated and will be removed in "
+ "Zope 2.11, you should use an IObjectAddedEvent "
+ "subscriber instead." % self.__class__.__name__,
+ DeprecationWarning, stacklevel=2)
+ manage_afterAdd.__five_method__ = True
def manage_beforeDelete(self, item, container):
- pass
+ warnings.warn(
+ "%s.manage_beforeDelete is deprecated and will be removed in "
+ "Zope 2.11, you should use an IObjectWillBeRemovedEvent "
+ "subscriber instead." % self.__class__.__name__,
+ DeprecationWarning, stacklevel=2)
+ manage_beforeDelete.__five_method__ = True
def manage_afterClone(self, item):
- pass
+ warnings.warn(
+ "%s.manage_afterClone is deprecated and will be removed in "
+ "Zope 2.11, you should use an IFiveObjectClonedEvent "
+ "subscriber instead." % self.__class__.__name__,
+ DeprecationWarning, stacklevel=2)
+ manage_afterClone.__five_method__ = True
# Direct use of the 'id' attribute is deprecated - use getId()
id=''
Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/BTreeFolder2/BTreeFolder2.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/BTreeFolder2/BTreeFolder2.py 2005-10-31 20:04:14 UTC (rev 39783)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/BTreeFolder2/BTreeFolder2.py 2005-10-31 20:09:39 UTC (rev 39784)
@@ -37,6 +37,11 @@
view_management_screens
from zLOG import LOG, INFO, ERROR, WARNING
from Products.ZCatalog.Lazy import LazyMap
+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
manage_addBTreeFolderForm = DTMLFile('folderAdd', globals())
@@ -404,48 +409,65 @@
'it is already in use.' % id)
- def _setObject(self, id, object, roles=None, user=None, set_owner=1):
- v=self._checkId(id)
- if v is not None: id=v
+ 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:
+ id = v
+
# If an object by the given id already exists, remove it.
if self.has_key(id):
self._delObject(id)
- self._setOb(id, object)
- object = self._getOb(id)
+ if not suppress_events:
+ notify(ObjectWillBeAddedEvent(ob, self, id))
+ self._setOb(id, ob)
+ ob = self._getOb(id)
+
if set_owner:
- object.manage_fixupOwnershipAfterAdd()
+ # TODO: eventify manage_fixupOwnershipAfterAdd
+ # This will be called for a copy/clone, or a normal _setObject.
+ ob.manage_fixupOwnershipAfterAdd()
# Try to give user the local role "Owner", but only if
# no local roles have been set on the object yet.
- if hasattr(object, '__ac_local_roles__'):
- if object.__ac_local_roles__ is None:
- user=getSecurityManager().getUser()
- if user is not None:
- userid=user.getId()
- if userid is not None:
- object.manage_setLocalRoles(userid, ['Owner'])
+ if getattr(ob, '__ac_local_roles__', _marker) is None:
+ user = getSecurityManager().getUser()
+ if user is not None:
+ userid = user.getId()
+ if userid is not None:
+ ob.manage_setLocalRoles(userid, ['Owner'])
- object.manage_afterAdd(object, self)
+ if not suppress_events:
+ notify(ObjectAddedEvent(ob, self, id))
+
+ maybeCallDeprecated('manage_afterAdd', ob, self)
+
return id
- def _delObject(self, id, dp=1):
- object = self._getOb(id)
- try:
- object.manage_beforeDelete(object, self)
- except BeforeDeleteException, ob:
- raise
- except ConflictError:
- raise
- except:
- LOG('Zope', ERROR, 'manage_beforeDelete() threw',
- error=sys.exc_info())
+ 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)
+
+ if not suppress_events:
+ notify(ObjectWillBeRemovedEvent(ob, self, id))
+
self._delOb(id)
+ if not suppress_events:
+ notify(ObjectRemovedEvent(ob, self, id))
+
# Aliases for mapping-like access.
__len__ = objectCount
keys = objectIds
More information about the Zope-Checkins
mailing list