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

Jim Fulton jim@zope.com
Mon, 23 Dec 2002 14:31:29 -0500


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

Added Files:
      Tag: NameGeddon-branch
	__init__.py btree.py configure.zcml dependency.py find.py 
	sample.py traversal.py zope.py 
Log Message:
Initial renaming before debugging

=== Added File Zope3/src/zope/app/container/__init__.py ===
#
# This file is necessary to make this directory a package.


=== Added File Zope3/src/zope/app/container/btree.py ===
##############################################################################
#
# 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: btree.py,v 1.1.2.1 2002/12/23 19:31:27 jim Exp $
"""

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()


=== Added File Zope3/src/zope/app/container/configure.zcml ===
<zopeConfigure xmlns='http://namespaces.zope.org/zope'>
 
  <adapter 
     provides="zope.app.interfaces.container.find.IFind"
     for="zope.app.interfaces.container.IReadContainer"
     permission="Zope.ManageContent" 
     factory="zope.app.container.find.FindAdapter" />
 
  <include package=".Views" />

</zopeConfigure>

<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"
>

  <include package=".Views" />

  <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.zope.ZopeContainerAdapter"
           provides="zope.app.interfaces.container.IZopeContainer"
           for="zope.app.interfaces.container.IContainer" />

  <event:subscribe 
      subscriber = ".DependencyChecker.CheckDependency"
      event_types = "Zope.App.Event.IObjectEvent.IObjectRemovedEvent"
      />


  <include package=".Find" />

</zopeConfigure>


=== Added File Zope3/src/zope/app/container/dependency.py ===
##############################################################################
#
# 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: dependency.py,v 1.1.2.1 2002/12/23 19:31:27 jim Exp $
"""
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()


=== Added File Zope3/src/zope/app/container/find.py ===
##############################################################################
#
# 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: find.py,v 1.1.2.1 2002/12/23 19:31:27 jim Exp $

"""

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.context import ContextWrapper

class FindAdapter(object):

    __implements__ =  IFind

    __used_for__ = IReadContainer
    
    def __init__(self, context):
        self._context = context
        
    ############################################################
    # Implementation methods for interface
    # Zope.App.OFS.Container.Find.IFind.IFind

    def find(self, id_filters=None, object_filters=None):
        'See Zope.App.OFS.Container.Find.IFind.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
        
    ############################################################
    # Implementation methods for interface
    # Zope.App.OFS.Container.Find.IFind.INameFindFilter

    def matches(self, id):
        'See Zope.App.OFS.Container.Find.IFind.INameFindFilter'
        return id in self._ids

    #
    ############################################################



=== Added File Zope3/src/zope/app/container/sample.py ===
##############################################################################
#
# 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: sample.py,v 1.1.2.1 2002/12/23 19:31:27 jim Exp $
"""

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 {}

    ############################################################
    # Implementation methods for interface
    # Zope.App.OFS.Container.IContainer

    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]

    #
    ############################################################


=== Added File Zope3/src/zope/app/container/traversal.py ===
##############################################################################
#
# 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: traversal.py,v 1.1.2.1 2002/12/23 19:31:27 jim Exp $
"""

from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.publisher.interfaces.xmlrpc import IXMLRPCPublisher
from zope.interfaces.publisher 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: traversal.py,v 1.1.2.1 2002/12/23 19:31:27 jim Exp $
"""

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



=== Added File Zope3/src/zope/app/container/zope.py ===
##############################################################################
#
# 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: zope.py,v 1.1.2.1 2002/12/23 19:31:27 jim Exp $
"""

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.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 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 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 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]

        publish(container, ObjectRemovedEvent(object))
        publish(container, ObjectModifiedEvent(container))

        return key