[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/registration/ Added suscriber to handle registerable component renames and moves. A rename updates the componentPath of component registrations. A move (to another container) is vetoed by raising a dependency error.

Garrett Smith garrett at mojave-corp.com
Wed Jul 7 19:15:42 EDT 2004


Log message for revision 26195:
Added suscriber to handle registerable component renames and moves. A rename updates the componentPath of component registrations. A move (to another container) is vetoed by raising a dependency error.


-=-
Modified: Zope3/trunk/src/zope/app/registration/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/registration/configure.zcml	2004-07-07 22:58:37 UTC (rev 26194)
+++ Zope3/trunk/src/zope/app/registration/configure.zcml	2004-07-07 23:15:42 UTC (rev 26195)
@@ -57,4 +57,10 @@
          zope.app.container.interfaces.IObjectAddedEvent"
     />
 
+  <subscriber
+    factory=".registration.RegisterableMoveSubscriber"
+    for=".interfaces.IRegisterable
+         zope.app.container.interfaces.IObjectMovedEvent"
+    />
+
 </configure>

Modified: Zope3/trunk/src/zope/app/registration/registration.py
===================================================================
--- Zope3/trunk/src/zope/app/registration/registration.py	2004-07-07 22:58:37 UTC (rev 26194)
+++ Zope3/trunk/src/zope/app/registration/registration.py	2004-07-07 23:15:42 UTC (rev 26195)
@@ -205,7 +205,7 @@
          False
 
        And register and activate r2:
-       
+
          >>> stack.register(r2)
          >>> stack.activate(r2)
          >>> stack.active()
@@ -220,7 +220,7 @@
          >>> stack.active()
 
        Because there wasn't an active registration before we made r2
-       active. 
+       active.
        """
 
 #     The invariants for _data are as follows:
@@ -463,7 +463,7 @@
          >>> stack.activate(r2)
 
        The parent will be notified of the activation and the
-       deactivation: 
+       deactivation:
 
          >>> parent.active
          r2
@@ -488,7 +488,7 @@
          r1
 
        And register and activate r2:
-       
+
          >>> stack.register(r2)
          >>> stack.activate(r2)
          >>> parent.active
@@ -505,7 +505,7 @@
          r2
 
        Because there wasn't an active registration before we made r2
-       active. 
+       active.
        """
 
     def _activate(self, registration):
@@ -647,6 +647,19 @@
     if adapter is not None:
         adapter.addUsage(objectpath)
 
+def RegisterableMoveSubscriber(registerable, event):
+    """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)
+            if registered is not None:
+                for reg in registered.registrations():
+                    if interfaces.IComponentRegistration.providedBy(reg):
+                        reg.componentPath = event.newName
+        else:
+            raise DependencyError(
+                "Can't move a registered component from its container.")
+
 from zope.app.dependable import PathSetAnnotation
 
 class Registered(PathSetAnnotation):
@@ -670,7 +683,7 @@
     def registrations(self):
         return [zapi.traverse(self.context, path)
                 for path in self.getPaths()]
-            
+
 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 22:58:37 UTC (rev 26194)
+++ Zope3/trunk/src/zope/app/registration/tests/test_registrations.py	2004-07-07 23:15:42 UTC (rev 26195)
@@ -23,6 +23,8 @@
 from zope.app.registration.interfaces import UnregisteredStatus
 from zope.app.registration.interfaces import RegisteredStatus
 from zope.app.registration.interfaces import ActiveStatus
+from zope.app.registration.interfaces import IRegisterable
+from zope.app.registration.interfaces import IRegistered
 from zope.app.dependable.interfaces import DependencyError
 from zope.app.registration.registration import \
      SimpleRegistration, ComponentRegistration
@@ -31,16 +33,19 @@
 from zope.app.traversing.api import traverse
 from zope.security.proxy import Proxy
 from zope.app.container.contained import Contained
-from zope.app.container.contained import ObjectRemovedEvent
+from zope.app.container.contained import ObjectRemovedEvent, ObjectMovedEvent
 from zope.app.tests import ztapi
 from zope.app.registration.interfaces import IRegistration
 from zope.app.container.interfaces import IObjectRemovedEvent
 from zope.app.registration.registration import \
     SimpleRegistrationRemoveSubscriber, \
     ComponentRegistrationRemoveSubscriber, \
-    ComponentRegistrationAddSubscriber
+    ComponentRegistrationAddSubscriber, \
+    RegisterableMoveSubscriber
+from zope.app.registration.registration import Registered
 from zope.app.traversing.interfaces import IPhysicallyLocatable
 import zope.interface
+from zope.app.annotation.interfaces import IAnnotations
 
 class ITestComponent(Interface):
     pass
@@ -72,16 +77,22 @@
 
     def __init__(self):
         self.status = UnregisteredStatus
-        
+
     def getPath(self):
         return 'dummy!'
 
     def getComponent(self):
         return self
-    
+
+
+class DummyRegisterable(Contained, dict):
+
+    implements(IRegisterable, IAnnotations)
+
+
 class TestSimpleRegistrationEvents(TestCase):
 
-    def test_RemoveSubscriber(self):    
+    def test_RemoveSubscriber(self):
         reg = DummyRegistration()
         reg.status = ActiveStatus
 
@@ -111,7 +122,7 @@
         SimpleRegistrationRemoveSubscriber(reg, event)
 
         self.assertEquals(reg.status, UnregisteredStatus)
-        
+
 class TestSimpleRegistration(TestCase):
 
     def setUp(self):
@@ -159,7 +170,7 @@
     def test_addNotify(self):
         """
         First we create a dummy registration
-        
+
           >>> reg = DummyRegistration()
 
         Now call notification
@@ -171,11 +182,11 @@
           >>> reg.dependents()
           ('dummy!',)
         """
-        
+
     def test_removeNotify_dependents(self):
         """
         First we create a dummy registration
-        
+
           >>> reg = DummyRegistration()
 
         Now call notification
@@ -195,9 +206,63 @@
 
           >>> reg.dependents()
           ()
-        
+
         """
 
+class TestRegisterableEvents:
+    """Tests handling of registered component rename.
+
+    >>> PlacefulSetup().setUp()
+
+    We'll first add a registerable component to the root folder:
+
+        >>> rootFolder = PlacefulSetup().rootFolder
+        >>> component = DummyRegisterable()
+        >>> rootFolder['foo'] = component
+
+    and create a registration for it:
+
+        >>> reg = ComponentRegistration("foo")
+        >>> rootFolder['reg'] = reg
+        >>> ztapi.provideAdapter(IRegisterable, IRegistered, Registered)
+        >>> IRegistered(component).addUsage('reg')
+
+    The registration is initially configured with the component path:
+
+        >>> reg.componentPath
+        'foo'
+
+    The RegisterableMoveSubscriber subscriber is for IRegisterable and
+    IObjectMovedEvent. When we invoke it with the appropriate 'rename' event
+    (i.e. oldParent is the same as newParent):
+
+        >>> event = ObjectMovedEvent(component,
+        ...     oldParent=rootFolder,
+        ...     oldName='foo',
+        ...     newParent=rootFolder,
+        ...     newName='bar')
+        >>> RegisterableMoveSubscriber(component, event)
+
+    the registration component path is updated accordingly:
+
+        >>> reg.componentPath
+        'bar'
+
+    However, if we invoke RegisterableMoveSubscriber with a 'move' event (i.e.
+    oldParent is different from newParent):
+
+        >>> event = ObjectMovedEvent(component,
+        ...     oldParent=rootFolder,
+        ...     oldName='foo',
+        ...     newParent=object(),
+        ...     newName='foo')
+        >>> RegisterableMoveSubscriber(component, event)
+        Traceback (most recent call last):
+        DependencyError: Can't move a registered component from its container.
+
+    >>> PlacefulSetup().tearDown()
+    """
+
 def test_suite():
     import sys
     return TestSuite((



More information about the Zope3-Checkins mailing list