[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/OFS/Container - IAddNotifiable.py:1.2 IDeleteNotifiable.py:1.2 IZopeContainer.py:1.2 ZopeContainerAdapter.py:1.2

Jim Fulton jim@zope.com
Mon, 18 Nov 2002 18:53:29 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Container
In directory cvs.zope.org:/tmp/cvs-serv25757

Added Files:
	IAddNotifiable.py IDeleteNotifiable.py IZopeContainer.py 
	ZopeContainerAdapter.py 
Log Message:
Created an adapter that provides Zope framework services for
containers, including:

  - Context wrapping

  - Event generation

  - Add and delete hooks

Modified the adding and contents views to use the new adapter.

Added interfaces defining add and delete hooks.





=== Zope3/lib/python/Zope/App/OFS/Container/IAddNotifiable.py 1.1 => 1.2 ===
--- /dev/null	Mon Nov 18 18:53:29 2002
+++ Zope3/lib/python/Zope/App/OFS/Container/IAddNotifiable.py	Mon Nov 18 18:52:58 2002
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Interface import Interface
+
+class IAddNotifiable(Interface):
+    """The Base interface for Manageing Objects
+    """
+    
+    def manage_afterAdd(object, container):
+        """Hook method will call after an object is added to container
+        """
\ No newline at end of file


=== Zope3/lib/python/Zope/App/OFS/Container/IDeleteNotifiable.py 1.1 => 1.2 ===
--- /dev/null	Mon Nov 18 18:53:29 2002
+++ Zope3/lib/python/Zope/App/OFS/Container/IDeleteNotifiable.py	Mon Nov 18 18:52:58 2002
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Interface import Interface
+
+class IDeleteNotifiable(Interface):
+    """The Base interface for Manageing Objects
+    """
+    
+    def manage_beforeDelete(object, container):
+        """Hook method will call before an object is removed from the container
+        """
\ No newline at end of file


=== Zope3/lib/python/Zope/App/OFS/Container/IZopeContainer.py 1.1 => 1.2 ===
--- /dev/null	Mon Nov 18 18:53:29 2002
+++ Zope3/lib/python/Zope/App/OFS/Container/IZopeContainer.py	Mon Nov 18 18:52:58 2002
@@ -0,0 +1,106 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+# 
+##############################################################################
+"""
+$Id$
+"""
+
+
+from Interface import Interface
+from Interface.Common.Mapping import IReadMapping, IEnumerableMapping
+
+class IZopeItemContainer(Interface):
+
+    def __getitem__(key):
+        """Return the content for the given key
+
+        Raises KeyError if the content can't be found.
+
+        The returned value will be in the context of the container.
+        """
+        
+
+
+class IZopeSimpleReadContainer(IZopeItemContainer, IReadMapping):
+    """Readable content containers
+    """
+
+    def get(key, default=None):
+        """Get a value for a key
+
+        The default is returned if there is no value for the key.
+        
+        The value for the key will be in the context of the container.         
+        """
+        
+    
+
+class IZopeReadContainer(IZopeSimpleReadContainer, IEnumerableMapping):
+    """Readable containers that can be enumerated.
+    """
+
+
+    def values():
+        """Return the values of the mapping object in the context of
+           the container
+        """
+
+    def items():
+        """Return the items of the mapping object in the context
+           of the container
+        """
+
+    
+
+class IZopeWriteContainer(Interface):
+    """An interface for the write aspects of a container."""
+
+    def setObject(key, object):
+        """Add the given object to the container under the given key.
+
+        Raises a ValueError if key is an empty string, unless the
+        context wrapper chooses a different key.
+
+        Returns the key used, which might be different than the given key.
+
+        If the object has an adpter to IAddNotifiable then the manageAfterAdd
+        method on the adpter will be called after the object is added.
+
+        An IObjectAddedEvent will be published after the object is added and
+        after manageAfterAdd is called. The event object will be the added
+        object in the context of the container
+
+        An IObjectModifiedEvent will be published after the IObjectAddedEvent
+        is published. The event object will be the container.                        
+        """
+
+    def __delitem__(key):
+        """Delete the keyd object from the context of the container.
+
+        Raises a KeyError if the object is not found.
+
+        If the object has an adpter to IDeleteNotifyObject then the
+        manageBeforeDeleteObject method on the adpter will be called before
+        the object is removed.
+
+        An IObjectRemovedEvent will be published before the object is
+        removed and before  manageBeforeDeleteObject is called.
+        The event object will be the removed from the context of the container
+
+        An IObjectModifiedEvent will be published after the IObjectRemovedEvent
+        is published. The event object will be the container.
+        """
+
+class IZopeContainer(IZopeReadContainer, IZopeWriteContainer):
+    """Readable and writable content container."""
+


=== Zope3/lib/python/Zope/App/OFS/Container/ZopeContainerAdapter.py 1.1 => 1.2 ===
--- /dev/null	Mon Nov 18 18:53:29 2002
+++ Zope3/lib/python/Zope/App/OFS/Container/ZopeContainerAdapter.py	Mon Nov 18 18:52:58 2002
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Zope.App.OFS.Container.IZopeContainer import IZopeContainer
+from Zope.ComponentArchitecture import queryAdapter
+from Zope.Proxy.ContextWrapper import ContextWrapper
+from Zope.Event import publishEvent
+from Zope.Event.ObjectEvent \
+     import ObjectRemovedEvent, ObjectModifiedEvent, ObjectAddedEvent
+from Zope.App.OFS.Container.IAddNotifiable import IAddNotifiable
+from Zope.App.OFS.Container.IDeleteNotifiable import IDeleteNotifiable
+from types import StringTypes
+from Zope.Proxy.ProxyIntrospection import removeAllProxies
+
+_marker = object()
+
+class ZopeContainerAdapter:
+    
+    __implements__ =  IZopeContainer
+
+    def __init__(self, container):
+        self.context = container
+        
+    def __getitem__(self, key):
+        "See Zope.App.OFS.Container.IZopeContainer.IZopeItemContainer"
+        value = self.context[key]
+        return ContextWrapper(value, self.context, name=key)
+
+    def get(self, key, default=None):
+        "See Zope.App.OFS.Container.IZopeContainer.IZopeSimpleReadContainer"
+        value = self.context.get(key, _marker)
+        if value is not _marker:
+            return ContextWrapper(value, self.context, name=key)
+        else:
+            return default
+
+    def __contains__(self, key):
+        '''See interface IReadContainer'''
+        return key in self.context
+            
+
+    def values(self):
+        "See Zope.App.OFS.Container.IZopeContainer.IZopeReadContainer"
+        container = self.context
+        result = []
+        for key, value in container.items():
+            result.append(ContextWrapper(value, container, 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 items(self):
+        "See Zope.App.OFS.Container.IZopeContainer.IZopeReadContainer"
+        container = self.context
+        result = []
+        for key, value in container.items():
+            result.append((key, ContextWrapper(value, container, name=key)))
+        return result
+        
+
+    def setObject(self, key, object):
+        "See Zope.App.OFS.Container.IZopeContainer.IZopeWriteContainer"
+        
+        if type(key) in StringTypes and len(key)==0:
+            raise ValueError("The id cannot be an empty string")
+
+        # We remove the proxies from the object before adding it to
+        # the container, because we can't store proxies.
+        object = removeAllProxies(object)
+
+        # Add the object
+        container = self.context
+        key = container.setObject(key, object)
+
+        # Publish an added event
+        object = ContextWrapper(container[key], container, name=key)
+        publishEvent(container, ObjectAddedEvent(object))
+
+        # Call the after add hook, if necessary
+        adapter = queryAdapter(object, IAddNotifiable)
+        if adapter is not None:
+            adapter.manage_afterAdd(object, container)
+
+        publishEvent(container, ObjectModifiedEvent(container))
+        return key
+
+    def __delitem__(self, key):
+        "See Zope.App.OFS.Container.IZopeContainer.IZopeWriteContainer"
+        container = self.context
+        
+        object = container[key]
+        object = ContextWrapper(object, container, name=key)
+        
+        # Call the before delete hook, if necessary
+        adapter = queryAdapter(object, IDeleteNotifiable)
+        if adapter is not None:
+            adapter.manage_beforeDelete(object, container)
+            
+            
+        del container[key]
+
+        publishEvent(container, ObjectRemovedEvent(object))
+        publishEvent(container, ObjectModifiedEvent(container))
+
+        return key