[Zope3-checkins] CVS: Zope3/src/zope/app/interfaces - context.py:1.2.4.1 zapi.py:1.7.2.1 copypastemove.py:1.4.16.1 dublincore.py:1.4.20.1 event.py:1.7.2.1 exceptions.py:1.1.18.1 form.py:1.2.22.1 fssync.py:1.2.4.1 introspector.py:1.2.26.1 talesapi.py:1.2.14.1 traversing.py:1.4.16.1

Grégoire Weber zope@i-con.ch
Sun, 22 Jun 2003 10:24:13 -0400


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

Modified Files:
      Tag: cw-mail-branch
	copypastemove.py dublincore.py event.py exceptions.py form.py 
	fssync.py introspector.py talesapi.py traversing.py 
Added Files:
      Tag: cw-mail-branch
	context.py zapi.py 
Log Message:
Synced up with HEAD

=== Added File Zope3/src/zope/app/interfaces/context.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.
#
##############################################################################
"""Interfaces related to context wrappers.

$Id: context.py,v 1.2.4.1 2003/06/22 14:23:11 gregweb Exp $
"""

from zope.interface import Interface
import zope.context.interfaces

class IContextWrapper(Interface):
    """Wrapper API provided to applications."""

    def ContextWrapper(object, parent, **data):
        """Create a context wrapper for object in parent

        If the object is in a security proxy, then result will be
        a security proxy for the unproxied object in context.

        Consider an object, o1, in a proxy p1 with a checker c1.

        If we call ContextWrapper(p1, parent, name='foo'), then we'll
        get::

          Proxy(Wrapper(o1, parent, name='foo'), c1)
        """

class IWrapper(zope.context.interfaces.IWrapper):
    """Base Context wrapper

    These objects extend context wrappers to:

    - Prevent pickling

    - To wrapper interface declarations.

    """
    
    def __reduce__():
        """Raises pickle.PicklingError if called (to prevent pickling)"""

    def __reduce_ex__(proto):
        """Raises pickle.PicklingError if called (to prevent pickling)"""

class IZopeContextWrapper(IWrapper):
    """Context wrappers that provide Zope framework support.

    This is a marker interface used to provide extra functionality,
    generally context-dependent, to make using objects in Zope more
    convenient.

    Decorators registered to provide IZopeContextWrapper will usually
    implement additional interfaces used by Zope.
    """


=== Added File Zope3/src/zope/app/interfaces/zapi.py ===
##############################################################################
#
# Copyright (c) 2003 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.
#
##############################################################################
"""Interface definition for the Zope convenience API module

$Id: zapi.py,v 1.7.2.1 2003/06/22 14:23:11 gregweb Exp $
"""
from zope.component.interfaces import IComponentArchitecture
from zope.app.interfaces.context import IContextWrapper
from zope.context.interfaces import IWrapperIntrospection
from zope.context.interfaces import IContextAwareDescriptorSupport
from zope.app.interfaces.traversing import ITraversalAPI

class IZAPI(
    IComponentArchitecture,
    IContextWrapper,
    IWrapperIntrospection,
    IContextAwareDescriptorSupport,
    ITraversalAPI,
    ):
    """Convenience API for use with Zope applications.
    """

    def name(obj):
        """Return an object's name

        This is the name the object is stored under in the container
        it was accessed in.  If the name is unknown, None is returned.
        """


=== Zope3/src/zope/app/interfaces/copypastemove.py 1.4 => 1.4.16.1 ===
--- Zope3/src/zope/app/interfaces/copypastemove.py:1.4	Mon Mar 31 09:48:41 2003
+++ Zope3/src/zope/app/interfaces/copypastemove.py	Sun Jun 22 10:23:11 2003
@@ -1,3 +1,200 @@
+##############################################################################
+#
+# Copyright (c) 2003 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.
+#
+##############################################################################
+"""Copy and Move support
+
+XXX The theory is unclear about whether copy and move are about
+    containers or not.  Many of the relevent interfaces are in
+    zope.app.interfaces.container, even though they are supposed not
+    to be indepenent of IContainer.
+
+    Perhaps we should just say that this is about containers and move
+    these interfaces there.
+
+
+Problem
+
+  Zope 3 needs to support three kinds of cut/copy/paste behaviour.
+
+  * Renaming an object to a different name in the same container.
+
+  * Moving an object from one place to another.
+
+  * Copying an object to another place.
+
+  The design for this needs to provide the right capabilities and
+  introspection to the user-interface. The appropriate events need
+  to be issued. The appropriate hooks, such as IDeleteNotifiable,
+  need to be called.
+
+
+Approach
+
+  Events and hooks
+
+    First, I need to explain events and hooks.
+
+    When an object is added to a container, if the object has an
+    IAddNotifiable adapter, that adapter's 'manage_afterAdd' method
+    is called. Then, an IObjectAddedEvent is published for the object.
+    Then an IObjectModifiedEvent is published for the container.
+
+    When an object is removed from a container, if the object has an
+    IDeleteNotifiable adapter, that adapter's 'manage_beforeDelete' method
+    is called. Then, an IObjectRemovedEvent is published for the object.
+    Then an IObjectModifiedEvent is published for the container.
+
+    When an object gets moved, it is a bit like being deleted and then added.
+    For many kinds of things you'd want to do in manage_afterAdd and
+    manage_beforeDelete, it is entirely appropriate to do these things
+    when an object is moved. However, in other cases you want special
+    behaviour on a move. So, IMoveNotifiable extends both IDeleteNotifiable
+    and IAddNotifiable, adds no further methods, but extends the method
+    signatures. This avoids the problem of an object that needs to be
+    notified of moves and of deletes, and do something different in each
+    case.
+
+    See zope.app.interrfaces.container.IMoveNotifiable and
+    zope.app.interrfaces.container.ICopyNotifiable.
+
+    The IZopeContainerAdapter is responsible for calling the hooks and
+    sending the events when you add or remove things from a container.
+
+  Renaming
+
+    Renaming an object is performed by moving it.
+
+    The ZopeContainerAdapter should be extended with a 'rename' method
+    for renaming an object in a container. This will be used by the
+    simple UI gesture for renaming something.
+
+    The rename method looks like this::
+
+      def rename(currentKey, newKey):
+          '''Put the object found at 'currentKey' under 'newKey' instead.
+
+          The container can choose different or modified 'newKey'. The
+          'newKey' that was used is returned.
+
+          If the object at 'currentKey' is IMoveNotifiable, its
+          manage_beforeDelete method is called, with a movingTo
+          argument of the container's path plus the 'newKey'.
+          Otherwise, if the object at 'currentKey' is IDeleteNotifiable,
+          its manage_beforeDelete method is called.
+
+          Then, the object is removed from the container using the
+          container's __del__ method.
+
+          Then, If the object is IMoveNotifiable, its manage_afterAdd
+          method is called, with a movedFrom argument of the container's
+          path plus the 'currentKey'.
+          Otherwise, if the object is IAddNotifiable, its manage_afterAdd
+          method is called.
+
+          Then, an IObjectMovedEvent is published.
+          '''
+
+   Note that zope.app.interfaces.event.IObjectMovedEvent extends
+   both zope.app.interfaces.event.IObjectRemovedEvent and
+   zope.app.interfaces.event.IObjectAddedEvent.
+
+   Similarly zope.app.interfaces.event.IObjectCopiedEvent extends
+   should be made to IObjectAddedEvent.
+
+ Moving and copying
+
+   IObjectMover is what you adapt an object to when you want to move
+   it. The adapter is responsible for calling the manage_beforeDelete and 
+   manage_afterAdd methods on an I(Add|Delete|Move)Notifiable adapter of
+   the object, as described above.
+   The IObjectMover adapter is also responsible for publishing an
+   IObjectMoved event in the context of the original container.
+
+   The 'moveTo()' method will get hold of an IMoveSource for
+   the object's container, and an IPasteTarget for the container the object
+   is being moved to.
+
+   Likewise, IObjectCopier is what you adapt an object to when you want to
+   copy it. The IObjectCopier adapter is responsible for calling a 
+   manage_afterAdd hook on an I(Add|Copy)Notifiable adapter of the object.
+
+  The zope.app.interrfaces.container.IPasteTarget,
+  zope.app.interrfaces.container.IMoveSource, and
+  zope.app.interrfaces.container.ICopySource interfaces are designed
+  to be independent of IContainer.  Adapters will be available for
+  IContainer, though. The idea is that it should be easy for
+  non-container classes to implement copy and paste, without having to
+  be containers.
+
+  A zope.app.interrfaces.container.IPasteTarget adapter must be
+  available for the object you want to copy or move something into.
+
+  A zope.app.interrfaces.container.IMoveSource adapter must be
+  available for an object you want to move something from.
+
+  Similarly, a zope.app.interrfaces.container.ICopySource adapter must
+  be available for an object you want to copy something from.
+
+Stepped out examples
+
+  These examples are simplified, and assume things, such as that an 
+  IPasteTarget adapter is unconditionally available, and copying across
+  databases is not supported.
+
+  Copying the object at '/foo/bar/baz' to '/fish/tree/zab'
+
+    Basic application code::
+
+      obj = traverse(context, '/foo/bar/baz')
+      target = traverse(context, '/fish/tree')
+      copier = getAdapter(obj, IObjectCopier)
+      if copier.copyableTo(target, 'zab'):
+          copier.copy(target, 'zab')
+
+    Inside the 'copier.copyableTo()' method::
+
+      def copyableTo(self, target, name=None):
+          obj = self.context
+          if name is None:
+              name = getName(obj)
+          pastetarget = getAdapter(target, IPasteTarget)
+          return pastetarget.acceptsObject(name, obj)
+
+    Inside the 'copier.copy()' method::
+
+      def copy(self, target, name=None):
+          obj = self.context
+          if name is None:
+              name = getName(obj)
+          copysource = getAdapter(getParent(obj), ICopySource)
+          obj = copysource.copyObject(name, target)
+          pastetarget = getAdapter(target, IPasteTarget)
+          new_obj = self._pickle_then_unpickle(obj)
+          # publish an ObjectCreatedEvent (perhaps...?)
+          new_name = pastetarget.pasteObject(name, new_obj)
+          # call manage_afterAdd hook
+          # publish ObjectCopiedEvent
+          return new_name
+
+      def _pickle_then_unpickle(self, obj):
+          # Remove proxies from obj, pickle and then unpickle it. 
+          # Return the result. Or, something like that
+          ....
+
+
+$Id$
+"""
+
 from zope.interface import Interface
 
 class IObjectMover(Interface):


=== Zope3/src/zope/app/interfaces/dublincore.py 1.4 => 1.4.20.1 ===
--- Zope3/src/zope/app/interfaces/dublincore.py:1.4	Tue Feb 25 09:13:47 2003
+++ Zope3/src/zope/app/interfaces/dublincore.py	Sun Jun 22 10:23:11 2003
@@ -16,13 +16,202 @@
 """
 
 from zope.app.interfaces.annotation import IAnnotatable
-from zope.app.dublincore.general \
-     import IGeneralDublinCore, IWritableGeneralDublinCore
 from zope.interface import Interface
 from zope.schema import Text, TextLine, Datetime, Sequence
 
-# XXX This will need to be filled out more.
 
+class IDublinCoreElementItem(Interface):
+    """A qualified sublin core element"""
+
+    qualification = TextLine(title = u"Qualification",
+                         description = u"The element qualification"
+                         )
+
+    value = Text(title = u"Value",
+                 description = u"The element value",
+                 )
+
+
+class IGeneralDublinCore(Interface):
+    """Dublin-core data access interface
+
+    The Dublin Core, http://dublincore.org/, is a meta data standard
+    that specifies a set of standard data elements. It provides
+    flexibility of interpretation of these elements by providing for
+    element qualifiers that specialize the meaning of specific
+    elements. For example, a date element might have a qualifier, like
+    "creation" to indicate that the date is a creation date. In
+    addition, any element may be repeated. For some elements, like
+    subject, and contributor, this is obviously necessary, but for
+    other elements, like title and description, allowing repetitions
+    is not very useful and adds complexity.
+
+    This interface provides methods for retrieving data in full
+    generality, to be complient with the dublin core standard.
+    Other interfaces will provide more convenient access methods
+    tailored to specific element usage patterns.
+    """
+
+    def getQualifiedTitles():
+        """Return a sequence of Title IDublinCoreElementItem.
+        """
+
+    def getQualifiedCreators():
+        """Return a sequence of Creator IDublinCoreElementItem.
+        """
+
+    def getQualifiedSubjects():
+        """Return a sequence of Subject IDublinCoreElementItem.
+        """
+
+    def getQualifiedDescriptions():
+        """Return a sequence of Description IDublinCoreElementItem.
+        """
+
+    def getQualifiedPublishers():
+        """Return a sequence of Publisher IDublinCoreElementItem.
+        """
+
+    def getQualifiedContributors():
+        """Return a sequence of Contributor IDublinCoreElementItem.
+        """
+
+    def getQualifiedDates():
+        """Return a sequence of Date IDublinCoreElementItem.
+        """
+
+    def getQualifiedTypes():
+        """Return a sequence of Type IDublinCoreElementItem.
+        """
+
+    def getQualifiedFormats():
+        """Return a sequence of Format IDublinCoreElementItem.
+        """
+
+    def getQualifiedIdentifiers():
+        """Return a sequence of Identifier IDublinCoreElementItem.
+        """
+
+    def getQualifiedSources():
+        """Return a sequence of Source IDublinCoreElementItem.
+        """
+
+    def getQualifiedLanguages():
+        """Return a sequence of Language IDublinCoreElementItem.
+        """
+
+    def getQualifiedRelations():
+        """Return a sequence of Relation IDublinCoreElementItem.
+        """
+
+    def getQualifiedCoverages():
+        """Return a sequence of Coverage IDublinCoreElementItem.
+        """
+
+    def getQualifiedRights():
+        """Return a sequence of Rights IDublinCoreElementItem.
+        """
+
+class IWritableGeneralDublinCore(Interface):
+    """Provide write access to dublin core data
+
+    This interface augments IStandardDublinCore with methods for
+    writing elements.
+    """
+
+    def setQualifiedTitles(qualified_titles):
+        """Set the qualified Title elements.
+
+        The argument must be a sequence of IDublinCoreElementItem.
+        """
+
+    def setQualifiedCreators(qualified_creators):
+        """Set the qualified Creator elements.
+
+        The argument must be a sequence of Creator IDublinCoreElementItem.
+        """
+
+    def setQualifiedSubjects(qualified_subjects):
+        """Set the qualified Subjects elements.
+
+        The argument must be a sequence of Subject IDublinCoreElementItem.
+        """
+
+    def setQualifiedDescriptions(qualified_descriptions):
+        """Set the qualified Descriptions elements.
+
+        The argument must be a sequence of Description IDublinCoreElementItem.
+        """
+
+    def setQualifiedPublishers(qualified_publishers):
+        """Set the qualified Publishers elements.
+
+        The argument must be a sequence of Publisher IDublinCoreElementItem.
+        """
+
+    def setQualifiedContributors(qualified_contributors):
+        """Set the qualified Contributors elements.
+
+        The argument must be a sequence of Contributor IDublinCoreElementItem.
+        """
+
+    def setQualifiedDates(qualified_dates):
+        """Set the qualified Dates elements.
+
+        The argument must be a sequence of Date IDublinCoreElementItem.
+        """
+
+    def setQualifiedTypes(qualified_types):
+        """Set the qualified Types elements.
+
+        The argument must be a sequence of Type IDublinCoreElementItem.
+        """
+
+    def setQualifiedFormats(qualified_formats):
+        """Set the qualified Formats elements.
+
+        The argument must be a sequence of Format IDublinCoreElementItem.
+        """
+
+    def setQualifiedIdentifiers(qualified_identifiers):
+        """Set the qualified Identifiers elements.
+
+        The argument must be a sequence of Identifier IDublinCoreElementItem.
+        """
+
+    def setQualifiedSources(qualified_sources):
+        """Set the qualified Sources elements.
+
+        The argument must be a sequence of Source IDublinCoreElementItem.
+        """
+
+    def setQualifiedLanguages(qualified_languages):
+        """Set the qualified Languages elements.
+
+        The argument must be a sequence of Language IDublinCoreElementItem.
+        """
+
+    def setQualifiedRelations(qualified_relations):
+        """Set the qualified Relations elements.
+
+        The argument must be a sequence of Relation IDublinCoreElementItem.
+        """
+
+    def setQualifiedCoverages(qualified_coverages):
+        """Set the qualified Coverages elements.
+
+        The argument must be a sequence of Coverage IDublinCoreElementItem.
+        """
+
+    def setQualifiedRights(qualified_rights):
+        """Set the qualified Rights elements.
+
+        The argument must be a sequence of Rights IDublinCoreElementItem.
+        """
+
+
+
+# XXX This will need to be filled out more.
 class IDCDescriptiveProperties(Interface):
     """Basic descriptive meta-data properties
     """
@@ -263,7 +452,6 @@
 
 class IZopeDublinCore(
     IGeneralDublinCore,
-    IWritableGeneralDublinCore,
     ICMFDublinCore,
     IDCDescriptiveProperties,
     IDCTimes,
@@ -271,6 +459,13 @@
     IDCExtended,
     ):
     """Zope Dublin Core properties"""
+
+class IWriteZopeDublinCore(
+    IZopeDublinCore,
+    IWritableGeneralDublinCore,
+    ):
+    """Zope Dublin Core properties with generate update support"""
+
 
 class IZopeDublinCoreAnnotatable(IAnnotatable):
     """Objects that can be annotated with Zope Dublin-Core meta data


=== Zope3/src/zope/app/interfaces/event.py 1.7 => 1.7.2.1 ===
--- Zope3/src/zope/app/interfaces/event.py:1.7	Tue May 20 12:57:52 2003
+++ Zope3/src/zope/app/interfaces/event.py	Sun Jun 22 10:23:11 2003
@@ -297,12 +297,12 @@
 class IObjectRemovedEvent(IObjectEvent):
     """An object has been removed from a container"""
 
-class IObjectMovedEvent(IObjectEvent):
+class IObjectMovedEvent(IObjectRemovedEvent, IObjectAddedEvent):
     """An object has been moved"""
 
     fromLocation = Attribute("The old location for the object.")
 
-class IObjectCopiedEvent(IObjectEvent):
+class IObjectCopiedEvent(IObjectAddedEvent):
     """An object has been copied"""
 
     fromLocation = Attribute("The old location for the object.")


=== Zope3/src/zope/app/interfaces/exceptions.py 1.1 => 1.1.18.1 ===
--- Zope3/src/zope/app/interfaces/exceptions.py:1.1	Fri Mar  7 07:06:37 2003
+++ Zope3/src/zope/app/interfaces/exceptions.py	Sun Jun 22 10:23:11 2003
@@ -13,9 +13,8 @@
 
 $Id$
 """
-__metaclass__ = type
 
-from zope.interface import Interface
+from zope.interface import Interface, implements
 
 class IUserError(Interface):
     """User error exceptions
@@ -27,5 +26,4 @@
     These exceptions should generally be displayed to users unless
     they are handled.
     """
-
-    __implements__ = IUserError
+    implements(IUserError)


=== Zope3/src/zope/app/interfaces/form.py 1.2 => 1.2.22.1 ===
--- Zope3/src/zope/app/interfaces/form.py:1.2	Fri Feb 21 12:52:19 2003
+++ Zope3/src/zope/app/interfaces/form.py	Sun Jun 22 10:23:11 2003
@@ -90,7 +90,7 @@
                                  defined for the widget.""")
 
     def getValue(name):
-        """Look up a Widget setting (value) by name."""
+        """Look up a Widget configuration setting by name."""
 
     def getData():
         """Return converted and validated widget data.
@@ -125,4 +125,12 @@
 
         The given value should be used even if the user has entered
         data.
+        """
+
+    def setPrefix(prefix):
+        """Set the name prefix used for the widget
+
+        The widget name is used to identify the widget's data within
+        input data. For example, for HTTP forms, the widget name is
+        used for the form key.
         """


=== Zope3/src/zope/app/interfaces/fssync.py 1.2 => 1.2.4.1 ===
--- Zope3/src/zope/app/interfaces/fssync.py:1.2	Mon May  5 14:01:02 2003
+++ Zope3/src/zope/app/interfaces/fssync.py	Sun Jun 22 10:23:11 2003
@@ -31,6 +31,13 @@
         objects that will be serialized to or from the file system.
         """
 
+    def annotations():
+        """Returns annotations data for the entry.
+
+        This behaves similar to extra().  The default implementation
+        might return queryAdapter(obj, IAnnotations).
+        """
+
     def typeIdentifier():
         """Return a dotted name that identifies the object type.
 
@@ -107,14 +114,3 @@
         A factory for a Synchronization Adapter is provided to create
         synchronizers for instances of the class.
         """
-
-
-class IFSAddView(IView):
-    """Add objects to ZODB from file system.
-
-    Implementation of this view helps in creating
-    file system representation for zope objects.
-    """
-
-    def create(fspath=None):
-        """Create file system representation for zope objects."""


=== Zope3/src/zope/app/interfaces/introspector.py 1.2 => 1.2.26.1 ===
--- Zope3/src/zope/app/interfaces/introspector.py:1.2	Wed Dec 25 09:12:56 2002
+++ Zope3/src/zope/app/interfaces/introspector.py	Sun Jun 22 10:23:11 2003
@@ -46,5 +46,5 @@
     def getExtends():
         """Returns all the class extended up to the top most level"""
 
-    def getInterfaceConfiguration():
+    def getInterfaceRegistration():
         """Returns details for a interface configuration"""


=== Zope3/src/zope/app/interfaces/talesapi.py 1.2 => 1.2.14.1 ===
--- Zope3/src/zope/app/interfaces/talesapi.py:1.2	Wed Apr 16 04:26:34 2003
+++ Zope3/src/zope/app/interfaces/talesapi.py	Sun Jun 22 10:23:11 2003
@@ -15,11 +15,27 @@
 
 $Id$
 """
+from zope.app.interfaces.dublincore import IDCDescriptiveProperties
+from zope.app.interfaces.dublincore import IDCTimes
 
-from zope.interface import Interface
+class IZopeTalesAPI(IDCDescriptiveProperties, IDCTimes):
 
-class IZopeTalesAPI(Interface):
+    def name():
+        """Return the object's name
 
-    def title():
-        """Return an object title
+        This is the name the object is stored under in the container
+        it was accessed in.
         """
+
+    def title_or_name():
+        """Return the title, if the is one, or the name otherwise
+        """
+
+    def size():
+        """Return a string representing the size of the object
+
+        This string could be a collection of digits or a descriptive
+        string of some sort.  If the size can't be determined
+        (e.g. the object has no size), an empty string is returned.
+        """
+    


=== Zope3/src/zope/app/interfaces/traversing.py 1.4 => 1.4.16.1 ===
--- Zope3/src/zope/app/interfaces/traversing.py:1.4	Mon Mar 24 11:42:21 2003
+++ Zope3/src/zope/app/interfaces/traversing.py	Sun Jun 22 10:23:11 2003
@@ -37,20 +37,6 @@
         It is not the respoonsibility of the handler to wrap the return value.
         """
 
-class IObjectName(Interface):
-
-    def __str__():
-        """Get a human-readable string representation
-        """
-
-    def __repr__():
-        """Get a string representation
-        """
-
-    def __call__():
-        """Get a string representation
-        """
-
 class IPhysicallyLocatable(Interface):
     """Objects that have a physical location in a containment hierarchy.
     """
@@ -63,6 +49,10 @@
         """Return the physical path to the object as a string.
         """
 
+    def getName():
+        """Return the last segment of the physical path.
+        """
+
 class ITraversable(Interface):
     """To traverse an object, this interface must be provided"""
 
@@ -102,4 +92,101 @@
         'request' is passed in when traversing from presentation code. This
         allows paths like @@foo to work.
         """
- 
+
+class ITraversalAPI(Interface):
+    """Common API functions to ease traversal computations
+    """
+
+    def joinPath(path, *args):
+        """Join the given relative paths to the given path.
+
+        Returns a unicode path.
+
+        The path should be well-formed, and not end in a '/' unless it is
+        the root path. It can be either a string (ascii only) or unicode.
+        The positional arguments are relative paths to be added to the
+        path as new path segments.  The path may be absolute or relative.
+
+        A segment may not start with a '/' because that would be confused
+        with an absolute path. A segment may not end with a '/' because we
+        do not allow '/' at the end of relative paths.  A segment may
+        consist of . or .. to mean "the same place", or "the parent path"
+        respectively. A '.' should be removed and a '..' should cause the
+        segment to the left to be removed.  joinPath('/', '..') should
+        raise an exception.
+        """
+
+    def getPath(obj):
+        """Returns a string representing the physical path to the object.
+        """
+
+    def getRoot(obj):
+        """Returns the root of the traversal for the given object.
+        """
+
+    def traverse(object, path, default=None, request=None):
+        """Traverse 'path' relative to the given object.
+
+        'path' is a string with path segments separated by '/'.
+
+        'request' is passed in when traversing from presentation code. This
+        allows paths like @@foo to work.
+
+        Raises NotFoundError if path cannot be found
+        Raises TypeError if place is not context wrapped
+
+        Note: calling traverse with a path argument taken from an untrusted
+              source, such as an HTTP request form variable, is a bad idea.
+              It could allow a maliciously constructed request to call
+              code unexpectedly.
+              Consider using traverseName instead.
+        """
+
+    def traverseName(obj, name, default=None, traversable=None,
+                     request=None):
+        """Traverse a single step 'name' relative to the given object.
+
+        'name' must be a string. '.' and '..' are treated specially, as well as
+        names starting with '@' or '+'. Otherwise 'name' will be treated as a
+        single path segment.
+
+        You can explicitly pass in an ITraversable as the
+        'traversable' argument. If you do not, the given object will
+        be adapted to ITraversable.
+
+        'request' is passed in when traversing from presentation code. This
+        allows paths like @@foo to work.
+
+        Raises NotFoundError if path cannot be found and 'default' was
+        not provided.
+
+        """
+
+    def getName(obj):
+        """Get the name an object was traversed via
+        """
+
+    def getParent(obj):
+        """Returns the container the object was traversed via.
+
+        Returns None if the object is a containment root.
+        Raises TypeError if the object doesn't have enough context to get the
+        parent.
+        """
+
+    def getParents(obj):
+        """Returns a list starting with the given object's parent followed by
+        each of its parents.
+
+        Raises a TypeError if the context doesn't go all the way down to
+        a containment root.
+        """
+
+    def canonicalPath(path_or_object):
+        """Returns a canonical absolute unicode path for the path or object.
+
+        Resolves segments that are '.' or '..'.
+
+        Raises ValueError if a badly formed path is given.
+        """
+