[Zope3-checkins] CVS: Zope3/src/zope/app/interfaces - copypastemove.py:1.7

Jim Fulton jim at zope.com
Sun Sep 21 13:30:09 EDT 2003


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

Modified Files:
	copypastemove.py 
Log Message:
Refactored the copy/paste/move framework:

- Got rid of CopySource, MoveSource, and PasteTarget.

- The mover and copier no longer generate events. This is done by
  containers.

- For now, allow moving copying between and only only between
  containers with the same class.  This will change when
  http://dev.zope.org/Zope3/ContainmentConstraints is done.

- Use INameChooser to pick new names when moving or copying.

- The copier and mover have to remove security proxied before saving
  in the container.  This used to be done by the containment
  decorator, so this is not a change of policy.

We need to think about the security model for copy and move.

- Got rid of the NoChildrenObjectCopier and associated interfaces and
  adapters.

Simpified the container interface to use __setitem__ rather than
setObject.

Added a "rename" helper function.


=== Zope3/src/zope/app/interfaces/copypastemove.py 1.6 => 1.7 ===
--- Zope3/src/zope/app/interfaces/copypastemove.py:1.6	Fri Jun 13 13:41:18 2003
+++ Zope3/src/zope/app/interfaces/copypastemove.py	Sun Sep 21 13:30:09 2003
@@ -13,185 +13,6 @@
 ##############################################################################
 """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$
 """
 
@@ -240,27 +61,12 @@
         False.
         '''
 
-class INoChildrenObjectCopier(IObjectCopier):
-    """Interface for adapters that can copy an containerish object
-    without its children"""
-
-    def copyTo(target, new_name=None):
-        """Copy this object without chidren to the target given.
-
-        Returns the new name within the target, or None
-        if the target doesn't do names.
-        Typically, the target is adapted to IPasteTarget.
-        After the copy is added to the target container, publish
-        an IObjectCopied event in the context of the target container.
-        If a new object is created as part of the copying process, then
-        an IObjectCreated event should be published.
-        """
-
 class IPrincipalClipboard(Interface):
     '''Interface for adapters that store/retrieve clipboard information
     for a principal.
 
-    Clipboard information consists on tuples of {'action':action, 'target':target}.
+    Clipboard information consists on tuples of
+      {'action':action, 'target':target}.
     '''
 
     def clearContents():




More information about the Zope3-Checkins mailing list