[Zope3-checkins] CVS: Zope3/src/zope/app/container - __init__.py:1.2 btree.py:1.2 configure.zcml:1.2 dependency.py:1.2 find.py:1.2 sample.py:1.2 traversal.py:1.2 zopecontainer.py:1.2

Jim Fulton jim@zope.com
Wed, 25 Dec 2002 09:13:48 -0500


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

Added Files:
	__init__.py btree.py configure.zcml dependency.py find.py 
	sample.py traversal.py zopecontainer.py 
Log Message:
Grand renaming:

- Renamed most files (especially python modules) to lower case.

- Moved views and interfaces into separate hierarchies within each
  project, where each top-level directory under the zope package
  is a separate project.

- Moved everything to src from lib/python.

  lib/python will eventually go away. I need access to the cvs
  repository to make this happen, however.

There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.



=== Zope3/src/zope/app/container/__init__.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/container/__init__.py	Wed Dec 25 09:12:46 2002
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.


=== Zope3/src/zope/app/container/btree.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/container/btree.py	Wed Dec 25 09:12:46 2002
@@ -0,0 +1,42 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""
+This module provides a sample container implementation.
+
+This is primarily for testing purposes.
+
+It might be useful as a mix-in for some classes, but many classes will
+need a very different implementation.
+
+Revision information:
+$Id$
+"""
+
+from persistence import Persistent
+from zodb.btrees.OOBTree import OOBTree
+from zope.app.container.sample import SampleContainer
+
+class BTreeContainer(SampleContainer, Persistent):
+
+    __implements__ = SampleContainer.__implements__, Persistent.__implements__
+
+    def _Container__newData(self):
+        """Construct an item-data container
+
+        Subclasses should override this if they want different data.
+
+        The value returned is a mapping object that also has get,
+        has_key, keys, items, and values methods.
+        """
+        return OOBTree()


=== Zope3/src/zope/app/container/configure.zcml 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/container/configure.zcml	Wed Dec 25 09:12:46 2002
@@ -0,0 +1,47 @@
+<zopeConfigure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:browser='http://namespaces.zope.org/browser'
+   xmlns:xmlrpc='http://namespaces.zope.org/xmlrpc'
+   xmlns:event="http://namespaces.zope.org/event"
+>
+
+  <adapter 
+     provides="zope.app.interfaces.container.find.IFind"
+     for="zope.app.interfaces.container.IReadContainer"
+     permission="zope.ManageContent" 
+     factory="zope.app.container.find.FindAdapter" />
+
+  <browser:view
+      name="_traverse" 
+      for="zope.app.interfaces.container.IItemContainer"
+      factory="zope.app.container.traversal.ItemTraverser" />
+
+  <browser:view
+      name="_traverse" 
+      for="zope.app.interfaces.container.ISimpleReadContainer"
+      factory="zope.app.container.traversal.ContainerTraverser" />
+
+  <xmlrpc:view
+      name="_traverse" 
+      for="zope.app.interfaces.container.IItemContainer"
+      factory="zope.app.container.traversal.ItemTraverser" />
+
+  <xmlrpc:view
+      name="_traverse" 
+      for="zope.app.interfaces.container.IReadContainer"
+      factory="zope.app.container.traversal.ContainerTraverser" />
+
+  <adapter factory="zope.app.container.traversal.ContainerTraversable"
+           provides="zope.app.interfaces.traversing.traversable.ITraversable"
+           for="zope.app.interfaces.container.IReadContainer" />
+
+  <adapter factory="zope.app.container.zopecontainer.ZopeContainerAdapter"
+           provides="zope.app.interfaces.container.IZopeContainer"
+           for="zope.app.interfaces.container.IContainer" />
+
+  <event:subscribe 
+      subscriber = ".dependency.CheckDependency"
+      event_types = "zope.app.interfaces.event.IObjectRemovedEvent"
+      />
+
+</zopeConfigure>


=== Zope3/src/zope/app/container/dependency.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/container/dependency.py	Wed Dec 25 09:12:46 2002
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 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.
+#
+##############################################################################
+"""Objects that take care of annotating dublin core meta data times
+
+$Id$
+"""
+from zope.component import queryAdapter
+from zope.app.interfaces.dependable import IDependable
+from zope.app.interfaces.dependable import DependencyError
+from zope.interfaces.event import ISubscriber
+from zope.proxy.introspection import removeAllProxies
+from zope.app.traversing import getPhysicalPathString, locationAsUnicode
+
+class DependencyChecker:
+    """Checking dependency  while deleting object
+    """
+    __implements__ = ISubscriber
+
+    def __init__(self):
+        pass
+
+    def notify(self, event):
+        object = removeAllProxies(event.object)
+        dependency = queryAdapter(object, IDependable)
+        if dependency is not None:
+            dependents = dependency.dependents()
+            if dependents:
+                objectpath = getPhysicalPathString(event.object)
+                dependents = map(locationAsUnicode, dependents)
+                raise DependencyError("Removal of object (%s)"
+                                      " which has dependents (%s)"
+                                      % (objectpath,
+                                         ", ".join(dependents)))
+
+CheckDependency = DependencyChecker()


=== Zope3/src/zope/app/container/find.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/container/find.py	Wed Dec 25 09:12:46 2002
@@ -0,0 +1,81 @@
+##############################################################################
+#
+# 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 zope.app.interfaces.container.find import IFind, IIdFindFilter
+from zope.app.interfaces.container import IReadContainer
+# XXX need to do this manually to wrap objects
+from zope.proxy.context import ContextWrapper
+
+class FindAdapter(object):
+
+    __implements__ =  IFind
+
+    __used_for__ = IReadContainer
+
+    def __init__(self, context):
+        self._context = context
+
+    def find(self, id_filters=None, object_filters=None):
+        'See IFind'
+        id_filters = id_filters or []
+        object_filters = object_filters or []
+        result = []
+        container = self._context
+        for id, object in container.items():
+            object = ContextWrapper(object, container, name=id)
+            _find_helper(id, object, container,
+                         id_filters, object_filters,
+                         result)
+        return result
+
+    #
+    ############################################################
+
+def _find_helper(id, object, container, id_filters, object_filters, result):
+    for id_filter in id_filters:
+        if not id_filter.matches(id):
+            break
+    else:
+        # if we didn't break out of the loop, all name filters matched
+        # now check all object filters
+        for object_filter in object_filters:
+            if not object_filter.matches(object):
+                break
+        else:
+            # if we didn't break out of the loop, all filters matched
+            result.append(object)
+
+    if not IReadContainer.isImplementedBy(object):
+        return
+
+    container = object
+    for id, object in container.items():
+        object = ContextWrapper(object, container, name=id)
+        _find_helper(id, object, container, id_filters, object_filters, result)
+
+class SimpleIdFindFilter(object):
+
+    __implements__ =  IIdFindFilter
+
+    def __init__(self, ids):
+        self._ids = ids
+
+    def matches(self, id):
+        'See INameFindFilter'
+        return id in self._ids


=== Zope3/src/zope/app/container/sample.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/container/sample.py	Wed Dec 25 09:12:46 2002
@@ -0,0 +1,101 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""
+This module provides a sample container implementation.
+
+This is primarily for testing purposes.
+
+It might be useful as a mix-in for some classes, but many classes will
+need a very different implementation.
+
+Revision information:
+$Id$
+"""
+
+from zope.app.interfaces.container import IContainer
+from types import StringTypes
+from zope.app.interfaces.container import UnaddableError
+
+class SampleContainer(object):
+    """Sample container implementation suitable for testing.
+
+    It is not suitable, directly as a base class unless the subclass
+    overrides _Container__newData to return a persistent mapping
+    object.
+    """
+
+    __implements__ =  IContainer
+
+    def __init__(self):
+        self.__data = self._Container__newData()
+
+    def _Container__newData(self):
+        """Construct an item-data container
+
+        Subclasses should override this if they want different data.
+
+        The value returned is a mapping object that also has get,
+        has_key, keys, items, and values methods.
+        """
+        return {}
+
+
+    def keys(self):
+        '''See interface IReadContainer'''
+        return self.__data.keys()
+
+    def __iter__(self):
+        return iter(self.__data.keys())
+
+    def __getitem__(self, key):
+        '''See interface IReadContainer'''
+        return self.__data[key]
+
+    def get(self, key, default=None):
+        '''See interface IReadContainer'''
+        return self.__data.get(key, default)
+
+    def values(self):
+        '''See interface IReadContainer'''
+        return self.__data.values()
+
+    def __len__(self):
+        '''See interface IReadContainer'''
+        return len(self.__data)
+
+    def items(self):
+        '''See interface IReadContainer'''
+        return self.__data.items()
+
+    def __contains__(self, key):
+        '''See interface IReadContainer'''
+        return self.__data.has_key(key)
+
+    has_key = __contains__
+
+    def setObject(self, key, object):
+        '''See interface IWriteContainer'''
+        if not isinstance(key, StringTypes):
+            raise TypeError("The key must be an ascii or unicode string")
+        if len(key) == 0:
+            raise ValueError("The key cannot be an empty string")
+        self.__data[key] = object
+        return key
+
+    def __delitem__(self, key):
+        '''See interface IWriteContainer'''
+        del self.__data[key]
+
+    #
+    ############################################################


=== Zope3/src/zope/app/container/traversal.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/container/traversal.py	Wed Dec 25 09:12:46 2002
@@ -0,0 +1,111 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Define view component for folder contents.
+
+$Id$
+"""
+
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.publisher.interfaces.xmlrpc import IXMLRPCPublisher
+from zope.publisher.interfaces import NotFound
+from zope.app.interfaces.container import ISimpleReadContainer, IItemContainer
+from zope.component import queryView
+from zope.component import getDefaultViewName
+
+
+class ContainerTraverser:
+
+    __implements__ = IBrowserPublisher, IXMLRPCPublisher
+    __used_for__ = ISimpleReadContainer
+
+    def __init__(self, container, request):
+        self.context = container
+        self.request = request
+
+    def publishTraverse(self, request, name):
+        c = self.context
+
+        subob = c.get(name, None)
+        if subob is None:
+
+            view = queryView(c, name, request)
+            if view is not None:
+                return view
+
+            raise NotFound(c, name, request)
+
+        return subob
+
+    def browserDefault(self, request):
+        c = self.context
+        view_name = getDefaultViewName(c, request)
+        view_uri = "@@%s" % view_name
+        return c, (view_uri,)
+
+
+class ItemTraverser(ContainerTraverser):
+
+    __used_for__ = IItemContainer
+
+    def publishTraverse(self, request, name):
+        context = self.context
+
+        try:
+            return context[name]
+
+        except KeyError:
+            view = queryView(context, name, request)
+            if view is not None:
+                return view
+
+        raise NotFound(context, name, request)
+
+
+"""
+Revision:
+$Id$
+"""
+
+from zope.app.interfaces.traversing.traversable import ITraversable
+from zope.app.traversing.exceptions import UnexpectedParameters
+from zope.app.interfaces.container import IReadContainer
+from zope.exceptions import NotFoundError
+from zope.component.exceptions import ComponentLookupError
+
+_marker = object()
+
+class ContainerTraversable:
+    """Traverses containers via getattr and get.
+    """
+
+    __implements__ = ITraversable
+    __used_for__ = IReadContainer
+
+    def __init__(self, container):
+        self._container = container
+
+
+    def traverse(self, name, parameters, original_name, furtherPath):
+        if parameters:
+            raise UnexpectedParameters(parameters)
+
+        container = self._container
+
+        v = container.get(name, _marker)
+        if v is _marker:
+            v = getattr(container, name, _marker)
+            if v is _marker:
+                raise NotFoundError, original_name
+
+        return v


=== Zope3/src/zope/app/container/zopecontainer.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:47 2002
+++ Zope3/src/zope/app/container/zopecontainer.py	Wed Dec 25 09:12:46 2002
@@ -0,0 +1,138 @@
+##############################################################################
+#
+# 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.interfaces.container import IZopeContainer
+from zope.app.interfaces.container import IOptionalNamesContainer
+from zope.app.interfaces.container import IContainerNamesContainer
+from zope.component import queryAdapter
+from zope.proxy.context import ContextWrapper
+from zope.event import publish
+from zope.app.event.objectevent \
+     import ObjectRemovedEvent, ObjectModifiedEvent, ObjectAddedEvent
+from zope.app.interfaces.container import IAddNotifiable
+from zope.app.interfaces.container import IDeleteNotifiable
+from types import StringTypes
+from zope.proxy.introspection import removeAllProxies
+
+_marker = object()
+
+class ZopeContainerAdapter:
+
+    __implements__ =  IZopeContainer
+
+    def __init__(self, container):
+        self.context = container
+
+    def __getitem__(self, key):
+        "See IZopeItemContainer"
+        value = self.context[key]
+        return ContextWrapper(value, self.context, name=key)
+
+    def get(self, key, default=None):
+        "See 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 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 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 IZopeWriteContainer"
+
+        if not isinstance(key, StringTypes):
+            raise TypeError("Item name is not a string.")
+
+        container = self.context
+
+        if not key:
+            if not (IOptionalNamesContainer.isImplementedBy(container)
+                    or IContainerNamesContainer.isImplementedBy(container)):
+                raise ValueError("Empty names are not allowed")
+
+        # 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
+        key = container.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))
+
+        # Call the after add hook, if necessary
+        adapter = queryAdapter(object, IAddNotifiable)
+        if adapter is not None:
+            adapter.manage_afterAdd(object, container)
+
+        publish(container, ObjectModifiedEvent(container))
+        return key
+
+    def __delitem__(self, key):
+        "See 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]
+
+        publish(container, ObjectRemovedEvent(object))
+        publish(container, ObjectModifiedEvent(container))
+
+        return key