[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/ Added a copier for
reigsterable objects that removes registered usages for the copy.
Garrett Smith
garrett at mojave-corp.com
Wed Jul 7 19:58:59 EDT 2004
Log message for revision 26197:
Added a copier for reigsterable objects that removes registered usages for the copy.
This resolves http://collector.zope.org/Zope3-dev/220
-=-
Modified: Zope3/trunk/src/zope/app/copypastemove/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/copypastemove/__init__.py 2004-07-07 23:17:29 UTC (rev 26196)
+++ Zope3/trunk/src/zope/app/copypastemove/__init__.py 2004-07-07 23:58:59 UTC (rev 26197)
@@ -373,11 +373,23 @@
copy = removeAllProxies(obj)
copy = locationCopy(copy)
- copy.__parent__ = copy.__name__ = None
+ self._configureCopy(copy, target, new_name)
notify(ObjectCopiedEvent(copy))
target[new_name] = copy
+ def _configureCopy(self, copy, target, new_name):
+ """Configures the copied object before it is added to target.
+
+ target and new_name are provided as additional information.
+
+ By default, copy.__parent__ and copy.__name__ are set to None.
+
+ Subclasses may override this method to perform additional
+ configuration of the copied object.
+ """
+ copy.__parent__ = copy.__name__ = None
+
def copyable(self):
'''Returns True if the object is copyable, otherwise False.'''
return True
Modified: Zope3/trunk/src/zope/app/registration/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/registration/configure.zcml 2004-07-07 23:17:29 UTC (rev 26196)
+++ Zope3/trunk/src/zope/app/registration/configure.zcml 2004-07-07 23:58:59 UTC (rev 26197)
@@ -16,7 +16,14 @@
provides=".interfaces.IRegistered"
factory=".registration.Registered"
/>
-
+
+ <adapter
+ for=".interfaces.IRegisterable"
+ provides="zope.app.copypastemove.interfaces.IObjectCopier"
+ factory=".registration.RegisterableCopier"
+ permission="zope.ManageContent"
+ />
+
<!-- Registration Manager -->
<content class=".registration.RegistrationManager">
Modified: Zope3/trunk/src/zope/app/registration/registration.py
===================================================================
--- Zope3/trunk/src/zope/app/registration/registration.py 2004-07-07 23:17:29 UTC (rev 26196)
+++ Zope3/trunk/src/zope/app/registration/registration.py 2004-07-07 23:58:59 UTC (rev 26197)
@@ -29,6 +29,7 @@
from zope.app.annotation.interfaces import IAttributeAnnotatable
from zope.app.container.contained import Contained
from zope.app.container.contained import setitem, contained, uncontained
+from zope.app.copypastemove import ObjectCopier
from zope.app.dependable.interfaces import IDependable, DependencyError
from zope.app.component.localservice import getLocalServices
from zope.app.location import inside
@@ -651,7 +652,7 @@
"""Updates componentPath for registrations on component rename."""
if event.oldParent is not None and event.newParent is not None:
if event.oldParent is event.newParent:
- registered = interfaces.IRegistered(registerable)
+ registered = interfaces.IRegistered(registerable, None)
if registered is not None:
for reg in registered.registrations():
if interfaces.IComponentRegistration.providedBy(reg):
@@ -670,6 +671,8 @@
"""
implements(interfaces.IRegistered)
+ __used_for__ = interfaces.IRegisterable
+
# We want to use this key:
# key = "zope.app.registration.Registered"
# But we have existing annotations with the following key, so we'll keep
@@ -684,6 +687,21 @@
return [zapi.traverse(self.context, path)
for path in self.getPaths()]
+class RegisterableCopier(ObjectCopier):
+ """Copies registerable components.
+
+ Performs the additional step of removing existing registered usages
+ for the new copy.
+ """
+ __used_for__ = interfaces.IRegisterable
+
+ def _configureCopy(self, copy, target, new_name):
+ ObjectCopier._configureCopy(self, copy, target, new_name)
+ registered = interfaces.IRegistered(copy, None)
+ if registered is not None:
+ for usage in registered.usages():
+ registered.removeUsage(usage)
+
class RegistrationManager(Persistent, Contained):
"""Registration manager
Modified: Zope3/trunk/src/zope/app/registration/tests/test_registrations.py
===================================================================
--- Zope3/trunk/src/zope/app/registration/tests/test_registrations.py 2004-07-07 23:17:29 UTC (rev 26196)
+++ Zope3/trunk/src/zope/app/registration/tests/test_registrations.py 2004-07-07 23:58:59 UTC (rev 26197)
@@ -43,6 +43,7 @@
ComponentRegistrationAddSubscriber, \
RegisterableMoveSubscriber
from zope.app.registration.registration import Registered
+from zope.app.registration.registration import RegisterableCopier
from zope.app.traversing.interfaces import IPhysicallyLocatable
import zope.interface
from zope.app.annotation.interfaces import IAnnotations
@@ -212,18 +213,18 @@
class TestRegisterableEvents:
"""Tests handling of registered component rename.
- >>> PlacefulSetup().setUp()
+ >>> sm = PlacefulSetup().setUp(site=True)
- We'll first add a registerable component to the root folder:
+ We'll first add a registerable component to the default site management
+ folder:
- >>> rootFolder = PlacefulSetup().rootFolder
>>> component = DummyRegisterable()
- >>> rootFolder['foo'] = component
+ >>> sm['default']['foo'] = component
and create a registration for it:
>>> reg = ComponentRegistration("foo")
- >>> rootFolder['reg'] = reg
+ >>> sm['default']['reg'] = reg
>>> ztapi.provideAdapter(IRegisterable, IRegistered, Registered)
>>> IRegistered(component).addUsage('reg')
@@ -237,9 +238,9 @@
(i.e. oldParent is the same as newParent):
>>> event = ObjectMovedEvent(component,
- ... oldParent=rootFolder,
+ ... oldParent=sm['default'],
... oldName='foo',
- ... newParent=rootFolder,
+ ... newParent=sm['default'],
... newName='bar')
>>> RegisterableMoveSubscriber(component, event)
@@ -252,7 +253,7 @@
oldParent is different from newParent):
>>> event = ObjectMovedEvent(component,
- ... oldParent=rootFolder,
+ ... oldParent=sm['default'],
... oldName='foo',
... newParent=object(),
... newName='foo')
@@ -263,6 +264,50 @@
>>> PlacefulSetup().tearDown()
"""
+class TestRegisterableCopier:
+ """Tests the copier for registerable components.
+
+ >>> sm = PlacefulSetup().setUp(site=True)
+
+ Registered components have annotation noting which registrations are
+ currently using the component. Copied components should not be noted
+ as used.
+
+ RegisterableCopier is used instead of the default object copier to
+ ensure that such usages are removed from the copied component.
+
+ To illustrate, we'll setup a component in the default site management
+ folder:
+
+ >>> component = DummyRegisterable()
+ >>> sm['default']['foo'] = component
+
+ and create a registration for it:
+
+ >>> reg = ComponentRegistration("foo")
+ >>> sm['default']['reg'] = reg
+ >>> ztapi.provideAdapter(IRegisterable, IRegistered, Registered)
+ >>> IRegistered(component).addUsage('/++etc++site/default/reg')
+
+ Note the current usages for the component:
+
+ >>> IRegistered(component).usages()
+ (u'/++etc++site/default/reg',)
+
+ Using RegisterableCopier, we can make a copy of the component:
+
+ >>> copier = RegisterableCopier(component)
+ >>> copier.copyTo(sm['default'], 'bar')
+
+ The copied component is not used:
+
+ >>> copy = sm['default']['bar']
+ >>> IRegistered(copy).usages()
+ ()
+
+ >>> PlacefulSetup().tearDown()
+ """
+
def test_suite():
import sys
return TestSuite((
More information about the Zope3-Checkins
mailing list