[Zope3-checkins] CVS: Zope3/src/zope/app/container - configure.zcml:1.10.14.1 zopecontainer.py:1.15.2.1

Steve Alexander steve@cat-box.net
Wed, 14 May 2003 13:44:41 -0400


Update of /cvs-repository/Zope3/src/zope/app/container
In directory cvs.zope.org:/tmp/cvs-serv32636/src/zope/app/container

Modified Files:
      Tag: stevea-decorators-branch
	configure.zcml zopecontainer.py 
Log Message:
Decorators are now really roughly integrated into zope on this branch.
Still to do:

  * The decorator registry needs an interface and some tests.

  * The decorator registry should be using a type registry rather than
    a simple dict, so that you don't need to keep declaring decorators
    for all the different subtypes of a container that doesn't manage
    its own context.

  * Fix various tests that explicitly use ZopeContainerAdapter.

  * Document use of decorators in Zope 3.

  * Get this work reviewed and discussed.

The first three points should be complete by the end of tomorrow.



=== Zope3/src/zope/app/container/configure.zcml 1.10 => 1.10.14.1 ===
--- Zope3/src/zope/app/container/configure.zcml:1.10	Mon Mar 31 09:48:40 2003
+++ Zope3/src/zope/app/container/configure.zcml	Wed May 14 13:44:10 2003
@@ -5,20 +5,20 @@
    xmlns:event="http://namespaces.zope.org/event"
 >
 
-  <adapter 
+  <adapter
      provides="zope.app.interfaces.container.find.IFind"
      for="zope.app.interfaces.container.IReadContainer"
      permission="zope.ManageContent" 
      factory="zope.app.container.find.FindAdapter" 
      />
 
-  <adapter 
+  <adapter
       for="zope.app.interfaces.container.IReadContainer"
       provides="zope.app.interfaces.file.IReadDirectory"
       factory=".directory.noop"
       />
 
-  <adapter 
+  <adapter
       for="zope.app.interfaces.container.IWriteContainer"
       provides="zope.app.interfaces.file.IWriteDirectory"
       factory=".directory.noop"
@@ -29,11 +29,20 @@
            for="zope.app.interfaces.container.IReadContainer" 
            />
 
+  <decorator
+      id="zope.app.container.contextdecorator"
+      class="zope.app.container.zopecontainer.ZopeContainerDecorator"
+      names="__getitem__ get __contains__ values items setObject
+             __delitem__ rename"
+      trusted="trusted">
+    <require permission="zope.ManageContent" attributes="rename" />
+  </decorator>
+<!--
   <adapter factory="zope.app.container.zopecontainer.ZopeContainerAdapter"
            provides="zope.app.interfaces.container.IZopeContainer"
            for="zope.app.interfaces.container.IContainer" 
            />
-
+  -->
   <adapter factory="zope.app.container.size.ContainerSized"
            provides="zope.app.interfaces.size.ISized"
            for="zope.app.interfaces.container.IContainer" 
@@ -66,7 +75,7 @@
      permission="zope.ManageContent" 
      factory="zope.app.container.copypastemove.PasteTarget" 
      />
-           
+
   <adapter 
      provides="zope.app.interfaces.container.IPasteNamesChooser"
      for="zope.app.interfaces.content.folder.IFolder"


=== Zope3/src/zope/app/container/zopecontainer.py 1.15 => 1.15.2.1 ===
--- Zope3/src/zope/app/container/zopecontainer.py:1.15	Thu May  8 06:57:55 2003
+++ Zope3/src/zope/app/container/zopecontainer.py	Wed May 14 13:44:10 2003
@@ -31,70 +31,66 @@
 from zope.exceptions import NotFoundError, DuplicationError
 from zope.app.event.objectevent \
      import ObjectRemovedEvent, ObjectModifiedEvent, ObjectAddedEvent
+from zope.interface import implements
 
 _marker = object()
 
-class ZopeContainerAdapter:
+class ZopeContainerDecorator:
 
-    __implements__ = IZopeContainer
-
-    def __init__(self, container):
-        self.context = container
+    implements(IZopeContainer)
 
     def __getitem__(self, key):
         "See IZopeItemContainer"
-        value = self.context[key]
-        return ContextWrapper(value, self.context, name=key)
+        value = self.inner[key]
+        return ContextWrapper(value, self.outer, name=key)
 
     def get(self, key, default=None):
         "See IZopeSimpleReadContainer"
-        value = self.context.get(key, _marker)
+        value = self.inner.get(key, _marker)
         if value is not _marker:
-            return ContextWrapper(value, self.context, name=key)
+            return ContextWrapper(value, self.outer, name=key)
         else:
             return default
 
     def __contains__(self, key):
         '''See interface IReadContainer'''
-        return key in self.context
-
+        return key in self.inner
 
     def values(self):
         "See IZopeReadContainer"
-        container = self.context
+        outer = self.outer
         result = []
-        for key, value in container.items():
-            result.append(ContextWrapper(value, container, name=key))
+        for key, value in self.inner.items():
+            result.append(ContextWrapper(value, outer, name=key))
         return result
 
-    def keys(self):
-        '''See interface IReadContainer'''
-        return self.context.keys()
-
-    def __len__(self):
-        '''See interface IReadContainer'''
-        return len(self.context)
+#    def keys(self):
+#        '''See interface IReadContainer'''
+#        return self.inner.keys()
+
+#    def __len__(self):
+#        '''See interface IReadContainer'''
+#        return len(self.context)
 
     def items(self):
         "See IZopeReadContainer"
-        container = self.context
+        outer = self.outer
         result = []
-        for key, value in container.items():
-            result.append((key, ContextWrapper(value, container, name=key)))
+        for key, value in self.inner.items():
+            result.append((key, ContextWrapper(value, outer, name=key)))
         return result
 
-
     def setObject(self, key, object):
         "See IZopeWriteContainer"
-
         if not isinstance(key, StringTypes):
             raise TypeError("Item name is not a string.")
 
-        container = self.context
+        inner = self.inner
+        outer = self.outer
 
         if not key:
-            if not (IOptionalNamesContainer.isImplementedBy(container)
-                    or IContainerNamesContainer.isImplementedBy(container)):
+            if not (IOptionalNamesContainer.isImplementedBy(inner)
+                    or IContainerNamesContainer.isImplementedBy(inner)):
                 raise ValueError("Empty names are not allowed")
 
         # We remove the proxies from the object before adding it to
@@ -102,50 +98,50 @@
         object = removeAllProxies(object)
 
         # Add the object
-        key = container.setObject(key, object)
+        key = inner.setObject(key, object)
 
         # Publish an added event
         # We explicitly get the object back from the container with
         # container[key], because some kinds of container may choose
         # to store a different object than the exact one we added.
-        object = ContextWrapper(container[key], container, name=key)
-        publish(container, ObjectAddedEvent(object))
+        object = ContextWrapper(container[key], outer, name=key)
+        publish(outer, ObjectAddedEvent(object))
 
         # Call the after add hook, if necessary
         adapter = queryAdapter(object, IAddNotifiable)
         if adapter is not None:
-            adapter.afterAddHook(object, container)
+            adapter.afterAddHook(object, outer)
 
-        publish(container, ObjectModifiedEvent(container))
+        publish(outer, ObjectModifiedEvent(outer))
         return key
 
     def __delitem__(self, key):
         "See IZopeWriteContainer"
-        container = self.context
+        outer = self.outer
 
         object = container[key]
-        object = ContextWrapper(object, container, name=key)
+        object = ContextWrapper(object, outer, name=key)
 
         # Call the before delete hook, if necessary
         adapter = queryAdapter(object, IDeleteNotifiable)
         if adapter is not None:
-            adapter.beforeDeleteHook(object, container)
+            adapter.beforeDeleteHook(object, outer)
         elif hasattr(object, 'beforeDeleteHook'):
             # XXX: Ideally, only do this in debug mode.
             from warnings import warn
             warn('Class %s has beforeDeleteHook but is not'
                  ' IDeleteNotifiable' % object.__class__)
 
-        del container[key]
+        del self.inner[key]
 
-        publish(container, ObjectRemovedEvent(object))
-        publish(container, ObjectModifiedEvent(container))
+        publish(outer, ObjectRemovedEvent(object))
+        publish(outer, ObjectModifiedEvent(outer))
 
         return key
 
-    def __iter__(self):
-        '''See interface IReadContainer'''
-        return iter(self.context)
+#    def __iter__(self):
+#        '''See interface IReadContainer'''
+#        return iter(self.context)
 
     def rename(self, currentKey, newKey):
         """Put the object found at 'currentKey' under 'newKey' instead.
@@ -170,19 +166,20 @@
 
         Then, an IObjectMovedEvent is published.
         """
+        inner = self.inner
+        outer = self.outer
 
         object = self.get(currentKey)
         if object is None:
-            raise NotFoundError(self.context, currentKey)
+            raise NotFoundError(outer, currentKey)
         mover = getAdapter(object, IObjectMover)
-        target = self.context
 
-        if target.__contains__(newKey):
+        if newKey in inner:
             raise DuplicationError("name, %s, is already in use" % newKey)
 
-        if mover.moveable() and mover.moveableTo(target, newKey):
+        if mover.moveable() and mover.moveableTo(outer, newKey):
             # the mover will call beforeDeleteHook hook for us
-            mover.moveTo(target, newKey)
+            mover.moveTo(outer, newKey)
             # the mover will call the afterAddHook hook for us
             # the mover will publish an ObjectMovedEvent for us