Commit a5ccd7a2 authored by 's avatar

- migrated some z2 interfaces to z3 interfaces, using Interface.bridge for backwards compatibility

- added some implements() declarations
parent b04834a6
...@@ -26,6 +26,10 @@ Zope Changes ...@@ -26,6 +26,10 @@ Zope Changes
Features added Features added
- AccessControl, Acquisition, App, OFS, webdav, PluginIndexes, ZCatalog
and ZCTextIndex: Added some Zope 3 style interfaces.
This makes the bridged interfaces shipped with Five obsolete.
- Interface: Added Z3 -> Z2 bridge utilities. - Interface: Added Z3 -> Z2 bridge utilities.
This allows to migrate interfaces to Zope 3 style interfaces and This allows to migrate interfaces to Zope 3 style interfaces and
bridge them back to oldstyle interfaces for backwards compatibility. bridge them back to oldstyle interfaces for backwards compatibility.
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Application support """Application support
...@@ -19,7 +19,7 @@ import os, sys, traceback ...@@ -19,7 +19,7 @@ import os, sys, traceback
from cgi import escape from cgi import escape
from StringIO import StringIO from StringIO import StringIO
import Globals, Products, App.Product, App.ProductRegistry, misc_ import Globals, Products, App.Product, App.ProductRegistry
import transaction import transaction
from AccessControl.User import UserFolder from AccessControl.User import UserFolder
from Acquisition import aq_base from Acquisition import aq_base
...@@ -29,14 +29,18 @@ from App.Product import doInstall ...@@ -29,14 +29,18 @@ from App.Product import doInstall
from App.ProductContext import ProductContext from App.ProductContext import ProductContext
from DateTime import DateTime from DateTime import DateTime
from HelpSys.HelpSys import HelpSys from HelpSys.HelpSys import HelpSys
from misc_ import Misc_
from webdav.NullResource import NullResource from webdav.NullResource import NullResource
from zExceptions import Redirect as RedirectException, Forbidden from zExceptions import Redirect as RedirectException, Forbidden
from zLOG import LOG, ERROR, WARNING, INFO from zLOG import LOG, ERROR, WARNING, INFO
from zope.interface import implements
import Folder import Folder
import misc_
import ZDOM import ZDOM
from FindSupport import FindSupport from FindSupport import FindSupport
from interfaces import IApplication
from misc_ import Misc_
class Application(Globals.ApplicationDefaultPermissions, class Application(Globals.ApplicationDefaultPermissions,
ZDOM.Root, Folder.Folder, ZDOM.Root, Folder.Folder,
...@@ -44,6 +48,8 @@ class Application(Globals.ApplicationDefaultPermissions, ...@@ -44,6 +48,8 @@ class Application(Globals.ApplicationDefaultPermissions,
"""Top-level system object""" """Top-level system object"""
implements(IApplication)
title ='Zope' title ='Zope'
#__roles__=['Manager', 'Anonymous'] #__roles__=['Manager', 'Anonymous']
__defined_roles__=('Manager','Anonymous','Owner') __defined_roles__=('Manager','Anonymous','Owner')
...@@ -401,7 +407,7 @@ class AppInitializer: ...@@ -401,7 +407,7 @@ class AppInitializer:
default_period_secs = 20 default_period_secs = 20
default_timeout_mins = 20 default_timeout_mins = 20
limit = getattr(config, 'maximum_number_of_session_objects', limit = getattr(config, 'maximum_number_of_session_objects',
default_limit) default_limit)
timeout_spec = getattr(config, 'session_timeout_minutes', timeout_spec = getattr(config, 'session_timeout_minutes',
default_timeout_mins) default_timeout_mins)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Copy interface """Copy interface
...@@ -23,12 +23,16 @@ from zlib import compress, decompress ...@@ -23,12 +23,16 @@ from zlib import compress, decompress
import Globals, Moniker, ExtensionClass import Globals, Moniker, ExtensionClass
import transaction import transaction
from App.Dialogs import MessageDialog
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from AccessControl.Permissions import delete_objects as DeleteObjects from AccessControl.Permissions import delete_objects as DeleteObjects
from Acquisition import aq_base, aq_inner, aq_parent from Acquisition import aq_base, aq_inner, aq_parent
from zExceptions import Unauthorized, BadRequest from App.Dialogs import MessageDialog
from webdav.Lockable import ResourceLockedError from webdav.Lockable import ResourceLockedError
from zExceptions import Unauthorized, BadRequest
from zope.interface import implements
from OFS.interfaces import ICopyContainer
from OFS.interfaces import ICopySource
CopyError='Copy Error' CopyError='Copy Error'
...@@ -42,6 +46,8 @@ class CopyContainer(ExtensionClass.Base): ...@@ -42,6 +46,8 @@ class CopyContainer(ExtensionClass.Base):
"""Interface for containerish objects which allow cut/copy/paste""" """Interface for containerish objects which allow cut/copy/paste"""
implements(ICopyContainer)
__ac_permissions__=( __ac_permissions__=(
('View management screens', ('View management screens',
('manage_copyObjects', 'manage_pasteObjects', ('manage_copyObjects', 'manage_pasteObjects',
...@@ -50,7 +56,6 @@ class CopyContainer(ExtensionClass.Base): ...@@ -50,7 +56,6 @@ class CopyContainer(ExtensionClass.Base):
('manage_cutObjects',)), ('manage_cutObjects',)),
) )
# The following three methods should be overridden to store sub-objects # The following three methods should be overridden to store sub-objects
# as non-attributes. # as non-attributes.
def _setOb(self, id, object): def _setOb(self, id, object):
...@@ -240,7 +245,6 @@ class CopyContainer(ExtensionClass.Base): ...@@ -240,7 +245,6 @@ class CopyContainer(ExtensionClass.Base):
cb_dataValid=0) cb_dataValid=0)
return result return result
manage_renameForm=Globals.DTMLFile('dtml/renameForm', globals()) manage_renameForm=Globals.DTMLFile('dtml/renameForm', globals())
def manage_renameObjects(self, ids=[], new_ids=[], REQUEST=None): def manage_renameObjects(self, ids=[], new_ids=[], REQUEST=None):
...@@ -430,11 +434,12 @@ class CopyContainer(ExtensionClass.Base): ...@@ -430,11 +434,12 @@ class CopyContainer(ExtensionClass.Base):
Globals.default__class_init__(CopyContainer) Globals.default__class_init__(CopyContainer)
class CopySource(ExtensionClass.Base): class CopySource(ExtensionClass.Base):
"""Interface for objects which allow themselves to be copied.""" """Interface for objects which allow themselves to be copied."""
implements(ICopySource)
# declare a dummy permission for Copy or Move here that we check # declare a dummy permission for Copy or Move here that we check
# in cb_isCopyable. # in cb_isCopyable.
__ac_permissions__=( __ac_permissions__=(
......
...@@ -7,10 +7,9 @@ ...@@ -7,10 +7,9 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""FTP Support for Zope classes. """FTP Support for Zope classes.
Preliminary FTP support interface. Note, most FTP functions are Preliminary FTP support interface. Note, most FTP functions are
...@@ -19,11 +18,20 @@ provided by existing methods such as PUT and manage_delObjects. ...@@ -19,11 +18,20 @@ provided by existing methods such as PUT and manage_delObjects.
All FTP methods should be governed by a single permission: All FTP methods should be governed by a single permission:
'FTP access'. 'FTP access'.
$Id$
""" """
from zope.interface import implements
from interfaces import IFTPAccess
class FTPInterface: class FTPInterface:
"Interface for FTP objects" "Interface for FTP objects"
implements(IFTPAccess)
# XXX The stat and list marshal format should probably # XXX The stat and list marshal format should probably
# be XML, not marshal, maybe Andrew K's xml-marshal. # be XML, not marshal, maybe Andrew K's xml-marshal.
# This will probably be changed later. # This will probably be changed later.
......
...@@ -7,26 +7,35 @@ ...@@ -7,26 +7,35 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Find support """Find support
$Id$ $Id$
""" """
import sys, os, time, Globals, ExtensionClass
from DocumentTemplate.DT_Util import Eval
from AccessControl.Permission import name_trans
from Globals import DTMLFile
from DocumentTemplate.DT_Util import InstanceDict, TemplateDict
from DateTime import DateTime
from string import translate from string import translate
from AccessControl.DTML import RestrictedDTML
import Globals, ExtensionClass
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from AccessControl.DTML import RestrictedDTML
from AccessControl.Permission import name_trans
from DateTime import DateTime
from DocumentTemplate.DT_Util import Eval
from DocumentTemplate.DT_Util import InstanceDict, TemplateDict
from Globals import DTMLFile
from zope.interface import implements
from interfaces import IFindSupport
class FindSupport(ExtensionClass.Base): class FindSupport(ExtensionClass.Base):
"""Find support for Zope Folders""" """Find support for Zope Folders"""
implements(IFindSupport)
#findframe is deprecated #findframe is deprecated
manage_findFrame=DTMLFile('dtml/findFrame', globals()) manage_findFrame=DTMLFile('dtml/findFrame', globals())
manage_findForm=DTMLFile('dtml/findForm', globals(), manage_findForm=DTMLFile('dtml/findForm', globals(),
...@@ -250,7 +259,7 @@ class FindSupport(ExtensionClass.Base): ...@@ -250,7 +259,7 @@ class FindSupport(ExtensionClass.Base):
return result return result
Globals.InitializeClass(FindSupport)
class td(RestrictedDTML, TemplateDict): class td(RestrictedDTML, TemplateDict):
...@@ -304,8 +313,6 @@ def role_match(ob, permission, roles, lt=type([]), tt=type(())): ...@@ -304,8 +313,6 @@ def role_match(ob, permission, roles, lt=type([]), tt=type(())):
return 1 return 1
Globals.InitializeClass(FindSupport)
# Helper functions # Helper functions
def absattr(attr): def absattr(attr):
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Folder object """Folder object
...@@ -16,14 +16,20 @@ Folders are the basic container objects and are analogous to directories. ...@@ -16,14 +16,20 @@ Folders are the basic container objects and are analogous to directories.
$Id$ $Id$
""" """
import Globals, SimpleItem, ObjectManager, PropertyManager
import AccessControl.Role, webdav.Collection, FindSupport import AccessControl.Role, webdav.Collection
from webdav.WriteLockInterface import WriteLockInterface import Globals
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from AccessControl import Unauthorized from AccessControl import Unauthorized
from AccessControl.Permissions import add_page_templates from AccessControl.Permissions import add_page_templates
from AccessControl.Permissions import add_user_folders from AccessControl.Permissions import add_user_folders
from Globals import DTMLFile from Globals import DTMLFile
from webdav.WriteLockInterface import WriteLockInterface
from zope.interface import implements
import FindSupport
import SimpleItem, ObjectManager, PropertyManager
from interfaces import IFolder
manage_addFolderForm=DTMLFile('dtml/folderAdd', globals()) manage_addFolderForm=DTMLFile('dtml/folderAdd', globals())
...@@ -72,12 +78,14 @@ class Folder( ...@@ -72,12 +78,14 @@ class Folder(
SimpleItem.Item, SimpleItem.Item,
FindSupport.FindSupport, FindSupport.FindSupport,
): ):
"""
Folders are basic container objects that provide a standard """Folders are basic container objects that provide a standard
interface for object management. Folder objects also implement interface for object management. Folder objects also implement
a management interface and can have arbitrary properties. a management interface and can have arbitrary properties.
""" """
__implements__ = (WriteLockInterface,) __implements__ = (WriteLockInterface,)
implements(IFolder)
meta_type='Folder' meta_type='Folder'
_properties=({'id':'title', 'type': 'string','mode':'wd'},) _properties=({'id':'title', 'type': 'string','mode':'wd'},)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
""" Order support interfaces. """ Order support interfaces.
...@@ -15,100 +15,14 @@ ...@@ -15,100 +15,14 @@
$Id$ $Id$
""" """
from Interface import Interface
# create IOrderedContainer
from Interface.bridge import createZope3Bridge
from OFS.interfaces import IOrderedContainer as z3IOrderedContainer
import IOrderSupport
class IOrderedContainer(Interface): createZope3Bridge(z3IOrderedContainer, IOrderSupport, 'IOrderedContainer')
""" Ordered Container interface.
This interface provides a common mechanism for maintaining ordered del createZope3Bridge
collections. del z3IOrderedContainer
""" del IOrderSupport
def moveObjectsByDelta(ids, delta, subset_ids=None):
""" Move specified sub-objects by delta.
If delta is higher than the possible maximum, objects will be moved to
the bottom. If delta is lower than the possible minimum, objects will
be moved to the top.
If subset_ids is not None, delta will be interpreted relative to the
subset specified by a sequence of ids. The position of objects that
are not part of this subset will not be changed.
The order of the objects specified by ids will always be preserved. So
if you don't want to change their original order, make sure the order
of ids corresponds to their original order.
If an object with id doesn't exist an error will be raised.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def moveObjectsUp(ids, delta=1, subset_ids=None):
""" Move specified sub-objects up by delta in container.
If no delta is specified, delta is 1. See moveObjectsByDelta for more
details.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def moveObjectsDown(ids, delta=1, subset_ids=None):
""" Move specified sub-objects down by delta in container.
If no delta is specified, delta is 1. See moveObjectsByDelta for more
details.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def moveObjectsToTop(ids, subset_ids=None):
""" Move specified sub-objects to top of container.
See moveObjectsByDelta for more details.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def moveObjectsToBottom(ids, subset_ids=None):
""" Move specified sub-objects to bottom of container.
See moveObjectsByDelta for more details.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def orderObjects(key, reverse=None):
""" Order sub-objects by key and direction.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def getObjectPosition(id):
""" Get the position of an object by its id.
Permission -- Access contents information
Returns -- Position
"""
def moveObjectToPosition(id, position):
""" Move specified object to absolute position.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Object Manager """Object Manager
...@@ -15,31 +15,34 @@ ...@@ -15,31 +15,34 @@
$Id$ $Id$
""" """
import sys, fnmatch, copy, os, re
import marshal import marshal
import sys, fnmatch, copy, os, re
from cgi import escape from cgi import escape
from cStringIO import StringIO from cStringIO import StringIO
from types import StringType, UnicodeType from types import StringType, UnicodeType
import App.Management, Acquisition, Globals, Products import App.Common
import App.FactoryDispatcher, Products import App.FactoryDispatcher, Products
import App.Management, Acquisition, Globals, Products
from AccessControl import getSecurityManager
from AccessControl.ZopeSecurityPolicy import getRoles
from Acquisition import aq_base
from App.config import getConfiguration
from Globals import DTMLFile, Persistent from Globals import DTMLFile, Persistent
from Globals import MessageDialog, default__class_init__ from Globals import MessageDialog, default__class_init__
from Globals import REPLACEABLE, NOT_REPLACEABLE, UNIQUE from Globals import REPLACEABLE, NOT_REPLACEABLE, UNIQUE
from webdav.NullResource import NullResource
from webdav.Collection import Collection from webdav.Collection import Collection
from Acquisition import aq_base
from webdav.Lockable import ResourceLockedError from webdav.Lockable import ResourceLockedError
from ZODB.POSException import ConflictError from webdav.NullResource import NullResource
import App.Common
from App.config import getConfiguration
from AccessControl import getSecurityManager
from AccessControl.ZopeSecurityPolicy import getRoles
from zLOG import LOG, ERROR
from zExceptions import BadRequest from zExceptions import BadRequest
from zLOG import LOG, ERROR
from ZODB.POSException import ConflictError
from zope.interface import implements
from OFS.Traversable import Traversable
import CopySupport import CopySupport
from interfaces import IObjectManager
from Traversable import Traversable
# the name BadRequestException is relied upon by 3rd-party code # the name BadRequestException is relied upon by 3rd-party code
BadRequestException = BadRequest BadRequestException = BadRequest
...@@ -122,6 +125,8 @@ class ObjectManager( ...@@ -122,6 +125,8 @@ class ObjectManager(
This class provides core behavior for collections of heterogeneous objects. This class provides core behavior for collections of heterogeneous objects.
""" """
implements(IObjectManager)
__ac_permissions__=( __ac_permissions__=(
('View management screens', ('manage_main',)), ('View management screens', ('manage_main',)),
('Access contents information', ('Access contents information',
...@@ -595,7 +600,7 @@ class ObjectManager( ...@@ -595,7 +600,7 @@ class ObjectManager(
paths.append(cfg.instancehome) paths.append(cfg.instancehome)
for impath in paths: for impath in paths:
directory = os.path.join(impath, 'import') directory = os.path.join(impath, 'import')
listing += [f for f in os.listdir(directory) listing += [f for f in os.listdir(directory)
if f.endswith('.zexp') or f.endswith('.xml')] if f.endswith('.zexp') or f.endswith('.xml')]
return listing return listing
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
""" Order support for 'Object Manager'. """ Order support for 'Object Manager'.
...@@ -23,12 +23,15 @@ from AccessControl.Permissions import manage_properties ...@@ -23,12 +23,15 @@ from AccessControl.Permissions import manage_properties
from Acquisition import aq_base from Acquisition import aq_base
from DocumentTemplate.sequence import sort from DocumentTemplate.sequence import sort
from Globals import InitializeClass from Globals import InitializeClass
from zope.interface import implements
from IOrderSupport import IOrderedContainer from interfaces import IOrderedContainer as z3IOrderedContainer
from IOrderSupport import IOrderedContainer as z2IOrderedContainer
from ObjectManager import ObjectManager from ObjectManager import ObjectManager
class OrderSupport: class OrderSupport:
""" Ordered container mixin class. """ Ordered container mixin class.
This is an extension to the regular ObjectManager. It saves the objects in This is an extension to the regular ObjectManager. It saves the objects in
...@@ -37,7 +40,8 @@ class OrderSupport: ...@@ -37,7 +40,8 @@ class OrderSupport:
is totally user-specific. is totally user-specific.
""" """
__implements__ = IOrderedContainer __implements__ = z2IOrderedContainer
implements(z3IOrderedContainer)
security = ClassSecurityInfo() security = ClassSecurityInfo()
has_order_support = 1 has_order_support = 1
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
""" 'Folder' with order support. """ 'Folder' with order support.
...@@ -20,8 +20,10 @@ from AccessControl import Unauthorized ...@@ -20,8 +20,10 @@ from AccessControl import Unauthorized
from AccessControl.Permissions import add_page_templates from AccessControl.Permissions import add_page_templates
from AccessControl.Permissions import add_user_folders from AccessControl.Permissions import add_user_folders
from Globals import DTMLFile from Globals import DTMLFile
from zope.interface import implements
from Folder import Folder from Folder import Folder
from interfaces import IOrderedFolder
from OrderSupport import OrderSupport from OrderSupport import OrderSupport
manage_addOrderedFolderForm = DTMLFile('dtml/addOrderedFolder', globals()) manage_addOrderedFolderForm = DTMLFile('dtml/addOrderedFolder', globals())
...@@ -61,10 +63,13 @@ def manage_addOrderedFolder(self, id, title='', createPublic=0, createUserF=0, ...@@ -61,10 +63,13 @@ def manage_addOrderedFolder(self, id, title='', createPublic=0, createUserF=0,
class OrderedFolder(OrderSupport, Folder): class OrderedFolder(OrderSupport, Folder):
""" Extends the default Folder by order support. """ Extends the default Folder by order support.
""" """
__implements__ = (OrderSupport.__implements__, __implements__ = (OrderSupport.__implements__,
Folder.__implements__) Folder.__implements__)
implements(IOrderedFolder)
meta_type='Folder (Ordered)' meta_type='Folder (Ordered)'
manage_options = ( OrderSupport.manage_options + manage_options = ( OrderSupport.manage_options +
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Property management """Property management
...@@ -19,13 +19,15 @@ from cgi import escape ...@@ -19,13 +19,15 @@ from cgi import escape
from types import ListType from types import ListType
import ExtensionClass, Globals import ExtensionClass, Globals
from ZPublisher.Converters import type_converters
from Globals import DTMLFile, MessageDialog
from Acquisition import aq_base from Acquisition import aq_base
from Globals import DTMLFile, MessageDialog
from Globals import Persistent from Globals import Persistent
from zExceptions import BadRequest from zExceptions import BadRequest
from zope.interface import implements
from ZPublisher.Converters import type_converters
import ZDOM import ZDOM
from interfaces import IPropertyManager
from PropertySheets import DefaultPropertySheets, vps from PropertySheets import DefaultPropertySheets, vps
...@@ -93,6 +95,8 @@ class PropertyManager(ExtensionClass.Base, ZDOM.ElementWithAttributes): ...@@ -93,6 +95,8 @@ class PropertyManager(ExtensionClass.Base, ZDOM.ElementWithAttributes):
'manage_changeProperties',)), 'manage_changeProperties',)),
""" """
implements(IPropertyManager)
manage_options=( manage_options=(
{'label':'Properties', 'action':'manage_propertiesForm', {'label':'Properties', 'action':'manage_propertiesForm',
'help':('OFSP','Properties.stx')}, 'help':('OFSP','Properties.stx')},
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""This module implements a simple item mix-in for objects that have a """This module implements a simple item mix-in for objects that have a
...@@ -22,22 +22,27 @@ $Id$ ...@@ -22,22 +22,27 @@ $Id$
import marshal, re, sys, time import marshal, re, sys, time
import Globals, App.Management, Acquisition, App.Undo
import AccessControl.Role, AccessControl.Owned, App.Common import AccessControl.Role, AccessControl.Owned, App.Common
from webdav.Resource import Resource import Globals, App.Management, Acquisition, App.Undo
from ExtensionClass import Base
from ComputedAttribute import ComputedAttribute
from AccessControl import getSecurityManager, Unauthorized from AccessControl import getSecurityManager, Unauthorized
from AccessControl.ZopeSecurityPolicy import getRoles from AccessControl.ZopeSecurityPolicy import getRoles
from Acquisition import aq_base, aq_parent, aq_inner, aq_acquire from Acquisition import aq_base, aq_parent, aq_inner, aq_acquire
from ComputedAttribute import ComputedAttribute
from DocumentTemplate.ustr import ustr from DocumentTemplate.ustr import ustr
from zExceptions.ExceptionFormatter import format_exception from ExtensionClass import Base
from webdav.Resource import Resource
from zExceptions import Redirect from zExceptions import Redirect
from zExceptions.ExceptionFormatter import format_exception
from zLOG import LOG, BLATHER from zLOG import LOG, BLATHER
from zope.interface import implements
import ZDOM
from CopySupport import CopySource from CopySupport import CopySource
from interfaces import IItem
from interfaces import IItemWithName
from interfaces import IManageable
from interfaces import ISimpleItem
from Traversable import Traversable from Traversable import Traversable
import ZDOM
HTML=Globals.HTML HTML=Globals.HTML
...@@ -50,6 +55,8 @@ class Item(Base, Resource, CopySource, App.Management.Tabs, Traversable, ...@@ -50,6 +55,8 @@ class Item(Base, Resource, CopySource, App.Management.Tabs, Traversable,
"""A common base class for simple, non-container objects.""" """A common base class for simple, non-container objects."""
implements(IItem, IManageable)
isPrincipiaFolderish=0 isPrincipiaFolderish=0
isTopLevelPrincipiaApplicationObject=0 isTopLevelPrincipiaApplicationObject=0
...@@ -216,7 +223,7 @@ class Item(Base, Resource, CopySource, App.Management.Tabs, Traversable, ...@@ -216,7 +223,7 @@ class Item(Base, Resource, CopySource, App.Management.Tabs, Traversable,
try: try:
strv = str(error_value) strv = str(error_value)
except: except:
strv = ('<unprintable %s object>' % strv = ('<unprintable %s object>' %
str(type(error_value).__name__)) str(type(error_value).__name__))
v = strv + ( v = strv + (
" (Also, an error occurred while attempting " " (Also, an error occurred while attempting "
...@@ -342,8 +349,11 @@ Globals.default__class_init__(Item) ...@@ -342,8 +349,11 @@ Globals.default__class_init__(Item)
class Item_w__name__(Item): class Item_w__name__(Item):
"""Mixin class to support common name/id functions""" """Mixin class to support common name/id functions"""
implements(IItemWithName)
def getId(self): def getId(self):
"""Return the id of the object as a string. """Return the id of the object as a string.
""" """
...@@ -397,6 +407,8 @@ class SimpleItem(Item, Globals.Persistent, ...@@ -397,6 +407,8 @@ class SimpleItem(Item, Globals.Persistent,
"""Mix-in class combining the most common set of basic mix-ins """Mix-in class combining the most common set of basic mix-ins
""" """
implements(ISimpleItem)
manage_options=Item.manage_options+( manage_options=Item.manage_options+(
{'label':'Security', {'label':'Security',
'action':'manage_access', 'action':'manage_access',
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""This module implements a mix-in for traversable objects. """This module implements a mix-in for traversable objects.
...@@ -17,18 +17,23 @@ $Id$ ...@@ -17,18 +17,23 @@ $Id$
from urllib import quote from urllib import quote
from Acquisition import Acquired, aq_inner, aq_parent, aq_base
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from AccessControl import Unauthorized from AccessControl import Unauthorized
from AccessControl.ZopeGuards import guarded_getattr from AccessControl.ZopeGuards import guarded_getattr
from ZODB.POSException import ConflictError from Acquisition import Acquired, aq_inner, aq_parent, aq_base
from zExceptions import NotFound from zExceptions import NotFound
from ZODB.POSException import ConflictError
from zope.interface import implements
from interfaces import ITraversable
_marker = object() _marker = object()
class Traversable: class Traversable:
implements(ITraversable)
absolute_url__roles__=None # Public absolute_url__roles__=None # Public
def absolute_url(self, relative=0): def absolute_url(self, relative=0):
"""Return the absolute URL of the object. """Return the absolute URL of the object.
...@@ -134,7 +139,7 @@ class Traversable: ...@@ -134,7 +139,7 @@ class Traversable:
if isinstance(path, str): if isinstance(path, str):
# Unicode paths are not allowed # Unicode paths are not allowed
path = path.split('/') path = path.split('/')
else: else:
path = list(path) path = list(path)
REQUEST = {'TraversalRequestNameStack': path} REQUEST = {'TraversalRequestNameStack': path}
...@@ -145,16 +150,16 @@ class Traversable: ...@@ -145,16 +150,16 @@ class Traversable:
# Remove trailing slash # Remove trailing slash
path.pop(0) path.pop(0)
if restricted: if restricted:
securityManager = getSecurityManager() securityManager = getSecurityManager()
else: else:
securityManager = _none securityManager = _none
if not path[-1]: if not path[-1]:
# If the path starts with an empty string, go to the root first. # If the path starts with an empty string, go to the root first.
path_pop() path_pop()
self = self.getPhysicalRoot() self = self.getPhysicalRoot()
if (restricted if (restricted
and not securityManager.validate(None, None, None, self)): and not securityManager.validate(None, None, None, self)):
raise Unauthorized, name raise Unauthorized, name
......
...@@ -29,16 +29,101 @@ from webdav.interfaces import IDAVCollection ...@@ -29,16 +29,101 @@ from webdav.interfaces import IDAVCollection
from webdav.interfaces import IDAVResource from webdav.interfaces import IDAVResource
# create IOrderedContainer class IOrderedContainer(Interface):
from Products.Five.fiveconfigure import createZope2Bridge
from OFS.IOrderSupport import IOrderedContainer as z2IOrderedContainer
import interfaces
createZope2Bridge(z2IOrderedContainer, interfaces, 'IOrderedContainer') """ Ordered Container interface.
del createZope2Bridge This interface provides a common mechanism for maintaining ordered
del z2IOrderedContainer collections.
del interfaces """
def moveObjectsByDelta(ids, delta, subset_ids=None):
""" Move specified sub-objects by delta.
If delta is higher than the possible maximum, objects will be moved to
the bottom. If delta is lower than the possible minimum, objects will
be moved to the top.
If subset_ids is not None, delta will be interpreted relative to the
subset specified by a sequence of ids. The position of objects that
are not part of this subset will not be changed.
The order of the objects specified by ids will always be preserved. So
if you don't want to change their original order, make sure the order
of ids corresponds to their original order.
If an object with id doesn't exist an error will be raised.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def moveObjectsUp(ids, delta=1, subset_ids=None):
""" Move specified sub-objects up by delta in container.
If no delta is specified, delta is 1. See moveObjectsByDelta for more
details.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def moveObjectsDown(ids, delta=1, subset_ids=None):
""" Move specified sub-objects down by delta in container.
If no delta is specified, delta is 1. See moveObjectsByDelta for more
details.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def moveObjectsToTop(ids, subset_ids=None):
""" Move specified sub-objects to top of container.
See moveObjectsByDelta for more details.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def moveObjectsToBottom(ids, subset_ids=None):
""" Move specified sub-objects to bottom of container.
See moveObjectsByDelta for more details.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def orderObjects(key, reverse=None):
""" Order sub-objects by key and direction.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
def getObjectPosition(id):
""" Get the position of an object by its id.
Permission -- Access contents information
Returns -- Position
"""
def moveObjectToPosition(id, position):
""" Move specified object to absolute position.
Permission -- Manage properties
Returns -- Number of moved sub-objects
"""
# XXX: might contain non-API methods and outdated comments; # XXX: might contain non-API methods and outdated comments;
...@@ -738,7 +823,8 @@ class IFolder(IObjectManager, IPropertyManager, IRoleManager, ...@@ -738,7 +823,8 @@ class IFolder(IObjectManager, IPropertyManager, IRoleManager,
"""Folders are basic container objects that provide a standard """Folders are basic container objects that provide a standard
interface for object management. Folder objects also implement a interface for object management. Folder objects also implement a
management interface and can have arbitrary properties.""" management interface and can have arbitrary properties.
"""
# XXX: based on OFS.OrderedFolder.OrderedFolder # XXX: based on OFS.OrderedFolder.OrderedFolder
......
...@@ -8,7 +8,7 @@ class TestApplication(unittest.TestCase): ...@@ -8,7 +8,7 @@ class TestApplication(unittest.TestCase):
from OFS.Application import Application from OFS.Application import Application
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IApplication, Application, 1) verifyClass(IApplication, Application)
def test_suite(): def test_suite():
......
...@@ -4,20 +4,17 @@ import Zope2 ...@@ -4,20 +4,17 @@ import Zope2
Zope2.startup() Zope2.startup()
import cStringIO import cStringIO
from mimetools import Message
from multifile import MultiFile
import transaction import transaction
from AccessControl import SecurityManager from AccessControl import SecurityManager
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import noSecurityManager
from Acquisition import Implicit
from Acquisition import aq_base from Acquisition import aq_base
from Acquisition import Implicit
from OFS.Application import Application from OFS.Application import Application
from OFS.Folder import manage_addFolder from OFS.Folder import manage_addFolder
from OFS.Image import manage_addFile from OFS.Image import manage_addFile
from Testing.makerequest import makerequest from Testing.makerequest import makerequest
from webdav.common import rfc1123_date
ADD_IMAGES_AND_FILES = 'Add images and files' ADD_IMAGES_AND_FILES = 'Add images and files'
...@@ -142,8 +139,8 @@ class TestCopySupport( CopySupportTestBase ): ...@@ -142,8 +139,8 @@ class TestCopySupport( CopySupportTestBase ):
from OFS.interfaces import ICopySource from OFS.interfaces import ICopySource
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(ICopyContainer, CopyContainer, 1) verifyClass(ICopyContainer, CopyContainer)
verifyClass(ICopySource, CopySource, 1) verifyClass(ICopySource, CopySource)
def testRename( self ): def testRename( self ):
self.failUnless( 'file' in self.folder1.objectIds() ) self.failUnless( 'file' in self.folder1.objectIds() )
...@@ -348,7 +345,7 @@ class TestCopySupportSecurity( CopySupportTestBase ): ...@@ -348,7 +345,7 @@ class TestCopySupportSecurity( CopySupportTestBase ):
except CopyError, e: except CopyError, e:
if ce_regex is not None: if ce_regex is not None:
pattern = re.compile( ce_regex, re.DOTALL ) pattern = re.compile( ce_regex, re.DOTALL )
if pattern.search( e ) is None: if pattern.search( e ) is None:
self.fail( "Paste failed; didn't match pattern:\n%s" % e ) self.fail( "Paste failed; didn't match pattern:\n%s" % e )
...@@ -362,7 +359,7 @@ class TestCopySupportSecurity( CopySupportTestBase ): ...@@ -362,7 +359,7 @@ class TestCopySupportSecurity( CopySupportTestBase ):
else: else:
self.fail( "Paste allowed unexpectedly." ) self.fail( "Paste allowed unexpectedly." )
def _initPolicyAndUser( self def _initPolicyAndUser( self
, a_lambda=None , a_lambda=None
, v_lambda=None , v_lambda=None
, c_lambda=None , c_lambda=None
...@@ -420,7 +417,7 @@ class TestCopySupportSecurity( CopySupportTestBase ): ...@@ -420,7 +417,7 @@ class TestCopySupportSecurity( CopySupportTestBase ):
) )
def test_copy_cant_create_target_metatype_not_supported( self ): def test_copy_cant_create_target_metatype_not_supported( self ):
from OFS.CopySupport import CopyError from OFS.CopySupport import CopyError
folder1, folder2 = self._initFolders() folder1, folder2 = self._initFolders()
...@@ -451,7 +448,7 @@ class TestCopySupportSecurity( CopySupportTestBase ): ...@@ -451,7 +448,7 @@ class TestCopySupportSecurity( CopySupportTestBase ):
self.failUnless( 'file' in folder2.objectIds() ) self.failUnless( 'file' in folder2.objectIds() )
def test_move_cant_read_source( self ): def test_move_cant_read_source( self ):
from OFS.CopySupport import CopyError from OFS.CopySupport import CopyError
folder1, folder2 = self._initFolders() folder1, folder2 = self._initFolders()
...@@ -471,7 +468,7 @@ class TestCopySupportSecurity( CopySupportTestBase ): ...@@ -471,7 +468,7 @@ class TestCopySupportSecurity( CopySupportTestBase ):
) )
def test_move_cant_create_target_metatype_not_supported( self ): def test_move_cant_create_target_metatype_not_supported( self ):
from OFS.CopySupport import CopyError from OFS.CopySupport import CopyError
folder1, folder2 = self._initFolders() folder1, folder2 = self._initFolders()
...@@ -486,7 +483,7 @@ class TestCopySupportSecurity( CopySupportTestBase ): ...@@ -486,7 +483,7 @@ class TestCopySupportSecurity( CopySupportTestBase ):
) )
def test_move_cant_create_target_metatype_not_allowed( self ): def test_move_cant_create_target_metatype_not_allowed( self ):
from OFS.CopySupport import CopyError from OFS.CopySupport import CopyError
folder1, folder2 = self._initFolders() folder1, folder2 = self._initFolders()
...@@ -505,7 +502,7 @@ class TestCopySupportSecurity( CopySupportTestBase ): ...@@ -505,7 +502,7 @@ class TestCopySupportSecurity( CopySupportTestBase ):
) )
def test_move_cant_delete_source( self ): def test_move_cant_delete_source( self ):
from OFS.CopySupport import CopyError from OFS.CopySupport import CopyError
from AccessControl.Permissions import delete_objects as DeleteObjects from AccessControl.Permissions import delete_objects as DeleteObjects
......
...@@ -8,7 +8,7 @@ class TestFTPInterface(unittest.TestCase): ...@@ -8,7 +8,7 @@ class TestFTPInterface(unittest.TestCase):
from OFS.FTPInterface import FTPInterface from OFS.FTPInterface import FTPInterface
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IFTPAccess, FTPInterface, 1) verifyClass(IFTPAccess, FTPInterface)
def test_suite(): def test_suite():
......
...@@ -8,7 +8,7 @@ class TestFindSupport(unittest.TestCase): ...@@ -8,7 +8,7 @@ class TestFindSupport(unittest.TestCase):
from OFS.FindSupport import FindSupport from OFS.FindSupport import FindSupport
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IFindSupport, FindSupport, 1) verifyClass(IFindSupport, FindSupport)
def test_suite(): def test_suite():
......
...@@ -16,8 +16,8 @@ class TestFolder(unittest.TestCase): ...@@ -16,8 +16,8 @@ class TestFolder(unittest.TestCase):
from webdav.interfaces import IWriteLock from webdav.interfaces import IWriteLock
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IFolder, Folder, 1) verifyClass(IFolder, Folder)
verifyClass(IWriteLock, Folder, 1) verifyClass(IWriteLock, Folder)
def test_suite(): def test_suite():
......
import unittest import unittest
from App.config import getConfiguration from AccessControl.Owned import EmergencyUserCannotOwn
from Acquisition import Implicit, aq_base, aq_parent
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.User import User
from AccessControl.SpecialUsers import emergency_user, nobody, system from AccessControl.SpecialUsers import emergency_user, nobody, system
from AccessControl.Owned import EmergencyUserCannotOwn, Owned from AccessControl.User import User
from Acquisition import Implicit
from App.config import getConfiguration
from OFS.ObjectManager import ObjectManager from OFS.ObjectManager import ObjectManager
from OFS.SimpleItem import SimpleItem from OFS.SimpleItem import SimpleItem
class FauxRoot( Implicit ): class FauxRoot( Implicit ):
id = '/' id = '/'
...@@ -75,7 +76,7 @@ class ObjectManagerTests( unittest.TestCase ): ...@@ -75,7 +76,7 @@ class ObjectManagerTests( unittest.TestCase ):
from OFS.ObjectManager import ObjectManager from OFS.ObjectManager import ObjectManager
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IObjectManager, ObjectManager, 1) verifyClass(IObjectManager, ObjectManager)
def test_setObject_set_owner_with_no_user( self ): def test_setObject_set_owner_with_no_user( self ):
...@@ -310,6 +311,7 @@ class ObjectManagerTests( unittest.TestCase ): ...@@ -310,6 +311,7 @@ class ObjectManagerTests( unittest.TestCase ):
om2._setObject(ob.getId(), ob) om2._setObject(ob.getId(), ob)
self.assertRaises(DeleteFailed, om1._delObject, 'om2') self.assertRaises(DeleteFailed, om1._delObject, 'om2')
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( ObjectManagerTests ) ) suite.addTest( unittest.makeSuite( ObjectManagerTests ) )
......
import unittest import unittest
import Testing
import Zope2
Zope2.startup()
from OFS.CopySupport import CopySource from OFS.CopySupport import CopySource
from OFS.ObjectManager import ObjectManager from OFS.ObjectManager import ObjectManager
...@@ -55,7 +52,7 @@ class TestOrderSupport(unittest.TestCase): ...@@ -55,7 +52,7 @@ class TestOrderSupport(unittest.TestCase):
from OFS.OrderSupport import OrderSupport from OFS.OrderSupport import OrderSupport
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IOrderedContainer, OrderSupport, 1) verifyClass(IOrderedContainer, OrderSupport)
def _doCanonTest(self, methodname, table): def _doCanonTest(self, methodname, table):
for args, order, rval in table: for args, order, rval in table:
......
...@@ -19,9 +19,9 @@ class TestOrderedFolder(unittest.TestCase): ...@@ -19,9 +19,9 @@ class TestOrderedFolder(unittest.TestCase):
from webdav.interfaces import IWriteLock from webdav.interfaces import IWriteLock
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IOrderedContainer, OrderedFolder, 1) verifyClass(IOrderedContainer, OrderedFolder)
verifyClass(IOrderedFolder, OrderedFolder, 1) verifyClass(IOrderedFolder, OrderedFolder)
verifyClass(IWriteLock, OrderedFolder, 1) verifyClass(IWriteLock, OrderedFolder)
def test_suite(): def test_suite():
......
############################################################################## ##############################################################################
# #
# Copyright (c) 2001, 2002 Zope Corporation and Contributors. # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
# All Rights Reserved.
# #
# This software is subject to the provisions of the Zope Public License, # 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. # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
...@@ -11,6 +10,10 @@ ...@@ -11,6 +10,10 @@
# FOR A PARTICULAR PURPOSE. # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Properties unit tests.
$Id$
"""
import unittest import unittest
...@@ -28,7 +31,7 @@ class TestPropertyManager(unittest.TestCase): ...@@ -28,7 +31,7 @@ class TestPropertyManager(unittest.TestCase):
from OFS.PropertyManager import PropertyManager from OFS.PropertyManager import PropertyManager
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IPropertyManager, PropertyManager, 1) verifyClass(IPropertyManager, PropertyManager)
def testLinesPropertyIsTuple( self ): def testLinesPropertyIsTuple( self ):
inst = self._makeOne() inst = self._makeOne()
......
...@@ -9,8 +9,8 @@ class TestItem(unittest.TestCase): ...@@ -9,8 +9,8 @@ class TestItem(unittest.TestCase):
from OFS.SimpleItem import Item from OFS.SimpleItem import Item
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IItem, Item, 1) verifyClass(IItem, Item)
verifyClass(IManageable, Item, 1) verifyClass(IManageable, Item)
class TestItem_w__name__(unittest.TestCase): class TestItem_w__name__(unittest.TestCase):
...@@ -20,7 +20,7 @@ class TestItem_w__name__(unittest.TestCase): ...@@ -20,7 +20,7 @@ class TestItem_w__name__(unittest.TestCase):
from OFS.SimpleItem import Item_w__name__ from OFS.SimpleItem import Item_w__name__
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IItemWithName, Item_w__name__, 1) verifyClass(IItemWithName, Item_w__name__)
class TestSimpleItem(unittest.TestCase): class TestSimpleItem(unittest.TestCase):
...@@ -30,7 +30,7 @@ class TestSimpleItem(unittest.TestCase): ...@@ -30,7 +30,7 @@ class TestSimpleItem(unittest.TestCase):
from OFS.SimpleItem import SimpleItem from OFS.SimpleItem import SimpleItem
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(ISimpleItem, SimpleItem, 1) verifyClass(ISimpleItem, SimpleItem)
def test_suite(): def test_suite():
......
############################################################################## ##############################################################################
# #
# Copyright (c) 2001, 2002 Zope Corporation and Contributors. # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
# All Rights Reserved.
# #
# This software is subject to the provisions of the Zope Public License, # 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. # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
...@@ -11,24 +10,26 @@ ...@@ -11,24 +10,26 @@
# FOR A PARTICULAR PURPOSE. # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Traverse unit tests.
import os, sys, unittest $Id$
import string, cStringIO, re """
import unittest
import cStringIO
import ZODB, Acquisition, transaction
import transaction import transaction
import ZODB, Acquisition, transaction
from AccessControl import SecurityManager, Unauthorized
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from Acquisition import aq_base from Acquisition import aq_base
from OFS.Application import Application from OFS.Application import Application
from OFS.Folder import manage_addFolder from OFS.Folder import manage_addFolder
from OFS.Image import manage_addFile from OFS.Image import manage_addFile
from OFS.SimpleItem import SimpleItem from OFS.SimpleItem import SimpleItem
from Testing.makerequest import makerequest from Testing.makerequest import makerequest
from AccessControl import SecurityManager, Unauthorized
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from mimetools import Message
from multifile import MultiFile
class UnitTestSecurityPolicy: class UnitTestSecurityPolicy:
...@@ -93,11 +94,11 @@ class BoboTraversable(SimpleItem): ...@@ -93,11 +94,11 @@ class BoboTraversable(SimpleItem):
return 42 return 42
else: else:
raise KeyError raise KeyError
def bb_method(self): def bb_method(self):
"""Test Method""" """Test Method"""
pass pass
bb_status = 'screechy' bb_status = 'screechy'
...@@ -168,20 +169,20 @@ class TestTraverse( unittest.TestCase ): ...@@ -168,20 +169,20 @@ class TestTraverse( unittest.TestCase ):
from OFS.Traversable import Traversable from OFS.Traversable import Traversable
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(ITraversable, Traversable, 1) verifyClass(ITraversable, Traversable)
def testTraversePath( self ): def testTraversePath( self ):
self.failUnless( 'file' in self.folder1.objectIds() ) self.failUnless( 'file' in self.folder1.objectIds() )
self.failUnless( self.failUnless(
self.folder1.unrestrictedTraverse( ('', 'folder1', 'file' ) )) self.folder1.unrestrictedTraverse( ('', 'folder1', 'file' ) ))
self.failUnless( self.failUnless(
self.folder1.unrestrictedTraverse( ('', 'folder1' ) )) self.folder1.unrestrictedTraverse( ('', 'folder1' ) ))
def testTraverseURLNoSlash( self ): def testTraverseURLNoSlash( self ):
self.failUnless( 'file' in self.folder1.objectIds() ) self.failUnless( 'file' in self.folder1.objectIds() )
self.failUnless( self.failUnless(
self.folder1.unrestrictedTraverse( '/folder1/file' )) self.folder1.unrestrictedTraverse( '/folder1/file' ))
self.failUnless( self.failUnless(
self.folder1.unrestrictedTraverse( '/folder1' )) self.folder1.unrestrictedTraverse( '/folder1' ))
def testTraverseURLSlash( self ): def testTraverseURLSlash( self ):
...@@ -190,12 +191,12 @@ class TestTraverse( unittest.TestCase ): ...@@ -190,12 +191,12 @@ class TestTraverse( unittest.TestCase ):
self.failUnless( self.folder1.unrestrictedTraverse( '/folder1/' )) self.failUnless( self.folder1.unrestrictedTraverse( '/folder1/' ))
def testTraverseToNone( self ): def testTraverseToNone( self ):
self.failUnlessRaises( self.failUnlessRaises(
KeyError, KeyError,
self.folder1.unrestrictedTraverse, ('', 'folder1', 'file2' ) ) self.folder1.unrestrictedTraverse, ('', 'folder1', 'file2' ) )
self.failUnlessRaises( self.failUnlessRaises(
KeyError, self.folder1.unrestrictedTraverse, '/folder1/file2' ) KeyError, self.folder1.unrestrictedTraverse, '/folder1/file2' )
self.failUnlessRaises( self.failUnlessRaises(
KeyError, self.folder1.unrestrictedTraverse, '/folder1/file2/' ) KeyError, self.folder1.unrestrictedTraverse, '/folder1/file2/' )
def testBoboTraverseToWrappedSubObj(self): def testBoboTraverseToWrappedSubObj(self):
...@@ -245,7 +246,7 @@ class TestTraverse( unittest.TestCase ): ...@@ -245,7 +246,7 @@ class TestTraverse( unittest.TestCase ):
self.root.stuff = 'stuff here' self.root.stuff = 'stuff here'
self.failUnlessRaises(Unauthorized, self.failUnlessRaises(Unauthorized,
self.root.folder1.restrictedTraverse, 'stuff') self.root.folder1.restrictedTraverse, 'stuff')
def testDefaultValueWhenUnathorized(self): def testDefaultValueWhenUnathorized(self):
# Test that traversing to an unauthorized object returns # Test that traversing to an unauthorized object returns
# the default when provided # the default when provided
...@@ -255,7 +256,7 @@ class TestTraverse( unittest.TestCase ): ...@@ -255,7 +256,7 @@ class TestTraverse( unittest.TestCase ):
self.root.stuff = 'stuff here' self.root.stuff = 'stuff here'
self.assertEqual( self.assertEqual(
self.root.folder1.restrictedTraverse('stuff', 42), 42) self.root.folder1.restrictedTraverse('stuff', 42), 42)
def testDefaultValueWhenNotFound(self): def testDefaultValueWhenNotFound(self):
# Test that traversing to a non-existent object returns # Test that traversing to a non-existent object returns
# the default when provided # the default when provided
...@@ -263,7 +264,7 @@ class TestTraverse( unittest.TestCase ): ...@@ -263,7 +264,7 @@ class TestTraverse( unittest.TestCase ):
SecurityManager.setSecurityPolicy( self.oldPolicy ) SecurityManager.setSecurityPolicy( self.oldPolicy )
self.assertEqual( self.assertEqual(
self.root.restrictedTraverse('happy/happy', 'joy'), 'joy') self.root.restrictedTraverse('happy/happy', 'joy'), 'joy')
def testTraverseUp(self): def testTraverseUp(self):
# Test that we can traverse upwards # Test that we can traverse upwards
self.failUnless( self.failUnless(
......
...@@ -7,94 +7,28 @@ ...@@ -7,94 +7,28 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Pluggable Index interfaces.
"""Pluggable Index Interface""" $Id$
__version__='$Revision: 1.9 $'[11:-2] """
import Interface
class PluggableIndexInterface(Interface.Base): # create PluggableIndexInterface, UniqueValueIndex, SortIndex
from Interface.bridge import createZope3Bridge
from Products.PluginIndexes.interfaces import IPluggableIndex
from Products.PluginIndexes.interfaces import ISortIndex
from Products.PluginIndexes.interfaces import IUniqueValueIndex
import PluggableIndex
def getId(): createZope3Bridge(IPluggableIndex, PluggableIndex, 'PluggableIndexInterface')
"""Return Id of index.""" createZope3Bridge(ISortIndex, PluggableIndex, 'SortIndex')
createZope3Bridge(IUniqueValueIndex, PluggableIndex, 'UniqueValueIndex')
def getEntryForObject(documentId, default=None): del createZope3Bridge
"""Get all information contained for 'documentId'.""" del IPluggableIndex
del ISortIndex
def getIndexSourceNames(): del IUniqueValueIndex
""" return a sequence of attribute names that are indexed del PluggableIndex
by the index.
"""
def index_object(documentId, obj, threshold=None):
"""Index an object.
'documentId' is the integer ID of the document.
'obj' is the object to be indexed.
'threshold' is the number of words to process between committing
subtransactions. If None, subtransactions are disabled.
"""
def unindex_object(documentId):
"""Remove the documentId from the index."""
def _apply_index(request, cid=''):
"""Apply the index to query parameters given in 'request'.
The argument should be a mapping object.
If the request does not contain the needed parametrs, then
None is returned.
If the request contains a parameter with the name of the column
+ "_usage", it is sniffed for information on how to handle applying
the index. (Note: this style or parameters is deprecated)
If the request contains a parameter with the name of the
column and this parameter is either a Record or a class
instance then it is assumed that the parameters of this index
are passed as attribute (Note: this is the recommended way to
pass parameters since Zope 2.4)
Otherwise two objects are returned. The first object is a
ResultSet containing the record numbers of the matching
records. The second object is a tuple containing the names of
all data fields used.
"""
def numObjects():
"""Return the number of indexed objects"""
def indexSize():
"""Return the size of the index in terms of distinct values"""
def clear():
"""Empty the index"""
class UniqueValueIndex(PluggableIndexInterface):
"""An index which can return lists of unique values contained in it"""
def hasUniqueValuesFor(name):
"""Return true if the index can return the unique values for name"""
def uniqueValues(name=None, withLengths=0):
"""Return the unique values for name.
If 'withLengths' is true, returns a sequence of tuples of
(value, length)."""
class SortIndex(PluggableIndexInterface):
"""An index which may be used to sort a set of document ids"""
def keyForDocument(documentId):
"""Return the sort key that cooresponds to the specified document id
This method is no longer used by ZCatalog, but is left for backwards
compatibility."""
def documentToKeyMap():
"""Return an object that supports __getitem__ and may be used to quickly
lookup the sort key given a document id"""
...@@ -19,8 +19,6 @@ from zope.interface import Interface ...@@ -19,8 +19,6 @@ from zope.interface import Interface
from zope.schema import Bool from zope.schema import Bool
# XXX: copied from common.PluggableIndex.PluggableIndexInterface;
# should be bridged
class IPluggableIndex(Interface): class IPluggableIndex(Interface):
def getId(): def getId():
...@@ -30,8 +28,7 @@ class IPluggableIndex(Interface): ...@@ -30,8 +28,7 @@ class IPluggableIndex(Interface):
"""Get all information contained for 'documentId'.""" """Get all information contained for 'documentId'."""
def getIndexSourceNames(): def getIndexSourceNames():
""" return a sequence of attribute names that are indexed """Get a sequence of attribute names that are indexed by the index.
by the index.
""" """
def index_object(documentId, obj, threshold=None): def index_object(documentId, obj, threshold=None):
...@@ -69,26 +66,24 @@ class IPluggableIndex(Interface): ...@@ -69,26 +66,24 @@ class IPluggableIndex(Interface):
records. The second object is a tuple containing the names of records. The second object is a tuple containing the names of
all data fields used. all data fields used.
""" """
def numObjects(): def numObjects():
"""Return the number of indexed objects""" """Return the number of indexed objects"""
# XXX: this is currently broken # XXX: not implemented by TextIndex and TopicIndex
# def indexSize(): # def indexSize():
# """Return the size of the index in terms of distinct values""" # """Return the size of the index in terms of distinct values"""
def clear(): def clear():
"""Empty the index""" """Empty the index"""
# XXX: copied from from common.PluggableIndex.UniqueValueIndex;
# should be bridged
class IUniqueValueIndex(IPluggableIndex): class IUniqueValueIndex(IPluggableIndex):
"""An index which can return lists of unique values contained in it""" """An index which can return lists of unique values contained in it"""
def hasUniqueValuesFor(name): def hasUniqueValuesFor(name):
"""Return true if the index can return the unique values for name""" """Return true if the index can return the unique values for name"""
def uniqueValues(name=None, withLengths=0): def uniqueValues(name=None, withLengths=0):
"""Return the unique values for name. """Return the unique values for name.
...@@ -96,17 +91,15 @@ class IUniqueValueIndex(IPluggableIndex): ...@@ -96,17 +91,15 @@ class IUniqueValueIndex(IPluggableIndex):
(value, length).""" (value, length)."""
# XXX: copied from from common.PluggableIndex.SortIndex;
# should be bridged
class ISortIndex(IPluggableIndex): class ISortIndex(IPluggableIndex):
"""An index which may be used to sort a set of document ids""" """An index which may be used to sort a set of document ids"""
def keyForDocument(documentId): def keyForDocument(documentId):
"""Return the sort key that cooresponds to the specified document id """Return the sort key that cooresponds to the specified document id
This method is no longer used by ZCatalog, but is left for backwards This method is no longer used by ZCatalog, but is left for backwards
compatibility.""" compatibility."""
def documentToKeyMap(): def documentToKeyMap():
"""Return an object that supports __getitem__ and may be used to quickly """Return an object that supports __getitem__ and may be used to quickly
lookup the sort key given a document id""" lookup the sort key given a document id"""
......
############################################################################## ##############################################################################
# #
# Copyright (c) 2002 Zope Corporation and Contributors. # Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
# All Rights Reserved.
# #
# This software is subject to the provisions of the Zope Public License, # 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. # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
...@@ -15,238 +14,13 @@ ...@@ -15,238 +14,13 @@
$Id$ $Id$
""" """
from Interface import Interface
class IZCatalog(Interface): # create IZCatalog
"""ZCatalog object from Interface.bridge import createZope3Bridge
from interfaces import IZCatalog as z3IZCatalog
import IZCatalog
A ZCatalog contains arbitrary index like references to Zope createZope3Bridge(z3IZCatalog, IZCatalog, 'IZCatalog')
objects. ZCatalog's can index object attribute using a variety
of "plug-in" index types.
Several index types are included, and others may be added. del createZope3Bridge
del z3IZCatalog
Text -- Text indexes index textual content. The index can be
used to search for objects containing certain words.
Field -- Field indexes index atomic values. The index can be
used to search for objects that have certain properties.
Keyword -- Keyword indexes index sequences of values. The index
can be used to search for objects that match one or more of the
search terms.
Path -- Path indexes index URI paths. They allow you to find objects
based on their placement in a hierarchy.
Date -- Date indexes index date and type data. They are a type of field
index specifically optimized for indexing dates.
Date Range -- Date range indexes index time intervals. They are designed
for efficient searching of dates falling between two boundaries
(such as effective / expiration dates).
Topic -- Topic indexes store prefiltered sets of documents. They are used
to optimize complex queries into a single fast query by prefiltering
documents by an expression
The ZCatalog can maintain a table of extra data about cataloged
objects. This information can be used on search result pages to
show information about a search result.
The meta-data table schema is used to build the schema for
ZCatalog Result objects. The objects have the same attributes
as the column of the meta-data table.
ZCatalog does not store references to the objects themselves, but
rather to a unique identifier that defines how to get to the
object. In Zope, this unique identifier is the object's relative
path to the ZCatalog (since two Zope objects cannot have the same
URL, this is an excellent unique qualifier in Zope).
"""
def catalog_object(obj, uid, idxs=None, update_metadata=1):
"""Catalogs the object 'obj' with the unique identifier 'uid'.
The uid must be a physical path, either absolute or relative to
the catalog.
If provided, idxs specifies the names of indexes to update.
If update_metadata is specified (the default), the object's metadata
is updated. If it is not, the metadata is left untouched. This
flag has no effect if the object is not yet cataloged (metadata
is always added for new objects).
"""
def uncatalog_object(uid):
"""Uncatalogs the object with the unique identifier 'uid'.
The uid must be a physical path, either absolute or relative to
the catalog.
"""
def uniqueValuesFor(name):
"""returns the unique values for a given FieldIndex named 'name'.
"""
def getpath(rid):
"""Return the path to a cataloged object given a 'data_record_id_'
"""
def getrid(rid):
"""Return the 'data_record_id_' to a cataloged object given a path
"""
def getobject(rid, REQUEST=None):
"""Return a cataloged object given a 'data_record_id_'
"""
def schema():
"""Get the meta-data schema
Returns a sequence of names that correspond to columns in the
meta-data table.
"""
def indexes():
"""Returns a sequence of names that correspond to indexes.
"""
def index_objects():
"""Returns a sequence of actual index objects.
NOTE: This returns unwrapped indexes! You should probably use
getIndexObjects instead. Some indexes expect to be wrapped.
"""
def getIndexObjects():
"""Returns a list of acquisition wrapped index objects
"""
def searchResults(REQUEST=None, **kw):
"""Search the catalog.
Search terms can be passed in the REQUEST or as keyword
arguments.
Search queries consist of a mapping of index names to search
parameters. You can either pass a mapping to searchResults as
the variable 'REQUEST' or you can use index names and search
parameters as keyword arguments to the method, in other words::
searchResults(title='Elvis Exposed',
author='The Great Elvonso')
is the same as::
searchResults({'title' : 'Elvis Exposed',
'author : 'The Great Elvonso'})
In these examples, 'title' and 'author' are indexes. This
query will return any objects that have the title *Elvis
Exposed* AND also are authored by *The Great Elvonso*. Terms
that are passed as keys and values in a searchResults() call
are implicitly ANDed together. To OR two search results, call
searchResults() twice and add concatenate the results like this::
results = ( searchResults(title='Elvis Exposed') +
searchResults(author='The Great Elvonso') )
This will return all objects that have the specified title OR
the specified author.
There are some special index names you can pass to change the
behavior of the search query:
sort_on -- This parameters specifies which index to sort the
results on.
sort_order -- You can specify 'reverse' or 'descending'.
Default behavior is to sort ascending.
sort_limit -- An optimization hint to tell the catalog how many
results you are really interested in. See the limit argument
to the search method for more details.
There are some rules to consider when querying this method:
- an empty query mapping (or a bogus REQUEST) returns all
items in the catalog.
- results from a query involving only field/keyword
indexes, e.g. {'id':'foo'} and no 'sort_on' will be
returned unsorted.
- results from a complex query involving a field/keyword
index *and* a text index,
e.g. {'id':'foo','PrincipiaSearchSource':'bar'} and no
'sort_on' will be returned unsorted.
- results from a simple text index query
e.g.{'PrincipiaSearchSource':'foo'} will be returned
sorted in descending order by 'score'. A text index
cannot beused as a 'sort_on' parameter, and attempting
to do so will raise an error.
Depending on the type of index you are querying, you may be
able to provide more advanced search parameters that can
specify range searches or wildcards. These features are
documented in The Zope Book.
"""
def __call__(REQUEST=None, **kw):
"""Search the catalog, the same way as 'searchResults'.
"""
def search(query_request, sort_index=None, reverse=0, limit=None, merge=1):
"""Programmatic search interface, use for searching the catalog from
scripts.
query_request -- Dictionary containing catalog query. This uses the
same format as searchResults.
sort_index -- Name of sort index
reverse -- Boolean, reverse sort order (defaults to false)
limit -- Limit sorted result count to the n best records. This is an
optimization hint used in conjunction with a sort_index. If possible
ZCatalog will use a different sort algorithm that uses much less memory
and scales better then a full sort. The actual number of records
returned is not guaranteed to be <= limit. You still need to apply the
same batching to the results. Since the len() of the results will no
longer be the actual result count, you can use the
"actual_result_count" attribute of the lazy result object instead to
determine the size of the full result set.
merge -- Return merged, lazy results (like searchResults) or raw
results for later merging. This can be used to perform multiple
queries (even across catalogs) and merge and sort the combined results.
"""
def refreshCatalog(clear=0, pghandler=None):
"""Reindex every object we can find, removing the unreachable
ones from the index.
clear -- values: 1|0 clear the catalog before reindexing
pghandler -- optional Progresshandler as defined in ProgressHandler.py
(see also README.txt)
"""
def reindexIndex(name, REQUEST, pghandler=None):
"""Reindex a single index.
name -- id of index
REQUEST -- REQUEST object
pghandler -- optional Progresshandler as defined in ProgressHandler.py
(see also README.txt)
"""
__doc__ = IZCatalog.__doc__ + __doc__
...@@ -18,8 +18,6 @@ $Id$ ...@@ -18,8 +18,6 @@ $Id$
from zope.interface import Interface from zope.interface import Interface
# XXX: copied from IZCatalog.IZCatalog;
# should be bridged
class IZCatalog(Interface): class IZCatalog(Interface):
"""ZCatalog object """ZCatalog object
...@@ -66,7 +64,6 @@ class IZCatalog(Interface): ...@@ -66,7 +64,6 @@ class IZCatalog(Interface):
object. In Zope, this unique identifier is the object's relative object. In Zope, this unique identifier is the object's relative
path to the ZCatalog (since two Zope objects cannot have the same path to the ZCatalog (since two Zope objects cannot have the same
URL, this is an excellent unique qualifier in Zope). URL, this is an excellent unique qualifier in Zope).
""" """
def catalog_object(obj, uid, idxs=None, update_metadata=1): def catalog_object(obj, uid, idxs=None, update_metadata=1):
...@@ -111,7 +108,6 @@ class IZCatalog(Interface): ...@@ -111,7 +108,6 @@ class IZCatalog(Interface):
Returns a sequence of names that correspond to columns in the Returns a sequence of names that correspond to columns in the
meta-data table. meta-data table.
""" """
def indexes(): def indexes():
...@@ -198,7 +194,6 @@ class IZCatalog(Interface): ...@@ -198,7 +194,6 @@ class IZCatalog(Interface):
able to provide more advanced search parameters that can able to provide more advanced search parameters that can
specify range searches or wildcards. These features are specify range searches or wildcards. These features are
documented in The Zope Book. documented in The Zope Book.
""" """
def __call__(REQUEST=None, **kw): def __call__(REQUEST=None, **kw):
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""WebDAV support - collection objects. """WebDAV support - collection objects.
...@@ -15,22 +15,31 @@ ...@@ -15,22 +15,31 @@
$Id$ $Id$
""" """
import Globals, davcmds, Lockable
from common import urlfix, rfc1123_date
from Resource import Resource
from AccessControl import getSecurityManager
from urllib import unquote from urllib import unquote
import Globals
from AccessControl import getSecurityManager
from zExceptions import MethodNotAllowed, NotFound from zExceptions import MethodNotAllowed, NotFound
from webdav.common import Locked, PreconditionFailed from zope.interface import implements
import davcmds
import Lockable
from common import Locked, PreconditionFailed
from common import urlfix, rfc1123_date
from interfaces import IDAVCollection
from Resource import Resource
class Collection(Resource): class Collection(Resource):
"""The Collection class provides basic WebDAV support for """The Collection class provides basic WebDAV support for
collection objects. It provides default implementations collection objects. It provides default implementations
for all supported WebDAV HTTP methods. The behaviors of some for all supported WebDAV HTTP methods. The behaviors of some
WebDAV HTTP methods for collections are slightly different WebDAV HTTP methods for collections are slightly different
than those for non-collection resources.""" than those for non-collection resources."""
implements(IDAVCollection)
__dav_collection__=1 __dav_collection__=1
def dav__init(self, request, response): def dav__init(self, request, response):
......
...@@ -7,10 +7,9 @@ ...@@ -7,10 +7,9 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""WebDAV support - resource objects. """WebDAV support - resource objects.
$Id$ $Id$
...@@ -20,29 +19,36 @@ import sys ...@@ -20,29 +19,36 @@ import sys
import mimetypes import mimetypes
from urllib import unquote from urllib import unquote
import Globals
import ExtensionClass import ExtensionClass
from Acquisition import aq_base import Globals
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from ZPublisher.HTTPRangeSupport import HTTPRangeInterface from Acquisition import aq_base
from zExceptions import BadRequest, MethodNotAllowed
from zExceptions import Unauthorized, Forbidden from zExceptions import Unauthorized, Forbidden
from zExceptions import BadRequest, MethodNotAllowed from zope.interface import implements
from ZPublisher.HTTPRangeSupport import HTTPRangeInterface
from WriteLockInterface import WriteLockInterface import davcmds
import Lockable import Lockable
from common import absattr, urlfix, rfc1123_date, tokenFinder, urlbase from common import absattr, urlfix, rfc1123_date, tokenFinder, urlbase
from common import IfParser from common import IfParser
from common import isDavCollection from common import isDavCollection
from common import Locked, Conflict, PreconditionFailed from common import Locked, Conflict, PreconditionFailed
import davcmds from interfaces import IDAVResource
from interfaces import IWriteLock
from WriteLockInterface import WriteLockInterface
class Resource(ExtensionClass.Base, Lockable.LockableItem): class Resource(ExtensionClass.Base, Lockable.LockableItem):
"""The Resource mixin class provides basic WebDAV support for """The Resource mixin class provides basic WebDAV support for
non-collection objects. It provides default implementations non-collection objects. It provides default implementations
for most supported WebDAV HTTP methods, however certain methods for most supported WebDAV HTTP methods, however certain methods
such as PUT should be overridden to ensure correct behavior in such as PUT should be overridden to ensure correct behavior in
the context of the object type.""" the context of the object type."""
implements(IDAVResource, IWriteLock)
__dav_resource__=1 __dav_resource__=1
__http_methods__=('GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS', __http_methods__=('GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS',
...@@ -598,5 +604,4 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -598,5 +604,4 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
def listDAVObjects(self): def listDAVObjects(self):
return [] return []
Globals.default__class_init__(Resource) Globals.default__class_init__(Resource)
...@@ -19,6 +19,7 @@ from Interface import Interface ...@@ -19,6 +19,7 @@ from Interface import Interface
class LockItemInterface(Interface): class LockItemInterface(Interface):
"""A LockItem contains information about a lock. """A LockItem contains information about a lock.
This includes: This includes:
...@@ -144,71 +145,12 @@ class LockItemInterface(Interface): ...@@ -144,71 +145,12 @@ class LockItemInterface(Interface):
used when returning the value of a newly created lock. """ used when returning the value of a newly created lock. """
class WriteLockInterface(Interface): # create WriteLockInterface
"""Basic protocol needed to support the write lock machinery. from Interface.bridge import createZope3Bridge
from interfaces import IWriteLock
It must be able to answer the questions: import WriteLockInterface
o Is the object locked?
o Is the lock owned by the current user?
o What lock tokens are associated with the current object?
o What is their state (how long until they're supposed to time out?,
what is their depth? what type are they?
And it must be able to do the following:
o Grant a write lock on the object to a specified user.
- *If lock depth is infinite, this must also grant locks on **all**
subobjects, or fail altogether*
o Revoke a lock on the object.
- *If lock depth is infinite, this must also revoke locks on all
subobjects*
**All methods in the WriteLock interface that deal with checking valid
locks MUST check the timeout values on the lockitem (ie, by calling
'lockitem.isValid()'), and DELETE the lock if it is no longer valid**
"""
def wl_lockItems(killinvalids=0):
""" Returns (key, value) pairs of locktoken, lock.
if 'killinvalids' is true, invalid locks (locks whose timeout
has been exceeded) will be deleted"""
def wl_lockValues(killinvalids=0):
""" Returns a sequence of locks. if 'killinvalids' is true,
invalid locks will be deleted"""
def wl_lockTokens(killinvalids=0):
""" Returns a sequence of lock tokens. if 'killinvalids' is true,
invalid locks will be deleted"""
def wl_hasLock(token, killinvalids=0):
""" Returns true if the lock identified by the token is attached
to the object. """
def wl_isLocked():
""" Returns true if 'self' is locked at all. If invalid locks
still exist, they should be deleted."""
def wl_setLock(locktoken, lock):
""" Store the LockItem, 'lock'. The locktoken will be used to fetch
and delete the lock. If the lock exists, this MUST
overwrite it if all of the values except for the 'timeout' on the
old and new lock are the same. """
def wl_getLock(locktoken):
""" Returns the locktoken identified by the locktokenuri """
def wl_delLock(locktoken): createZope3Bridge(IWriteLock, WriteLockInterface, 'WriteLockInterface')
""" Deletes the locktoken identified by the locktokenuri """
def wl_clearLocks(): del createZope3Bridge
""" Deletes ALL DAV locks on the object - should only be called del IWriteLock
by lock management machinery. """
...@@ -19,16 +19,75 @@ from zope.interface import Interface ...@@ -19,16 +19,75 @@ from zope.interface import Interface
from zope.schema import Bool, Tuple from zope.schema import Bool, Tuple
# create IWriteLock class IWriteLock(Interface):
from Products.Five.fiveconfigure import createZope2Bridge
from webdav.WriteLockInterface import WriteLockInterface
import interfaces
createZope2Bridge(WriteLockInterface, interfaces, 'IWriteLock') """Basic protocol needed to support the write lock machinery.
del createZope2Bridge It must be able to answer the questions:
del WriteLockInterface
del interfaces o Is the object locked?
o Is the lock owned by the current user?
o What lock tokens are associated with the current object?
o What is their state (how long until they're supposed to time out?,
what is their depth? what type are they?
And it must be able to do the following:
o Grant a write lock on the object to a specified user.
- *If lock depth is infinite, this must also grant locks on **all**
subobjects, or fail altogether*
o Revoke a lock on the object.
- *If lock depth is infinite, this must also revoke locks on all
subobjects*
**All methods in the WriteLock interface that deal with checking valid
locks MUST check the timeout values on the lockitem (ie, by calling
'lockitem.isValid()'), and DELETE the lock if it is no longer valid**
"""
def wl_lockItems(killinvalids=0):
""" Returns (key, value) pairs of locktoken, lock.
if 'killinvalids' is true, invalid locks (locks whose timeout
has been exceeded) will be deleted"""
def wl_lockValues(killinvalids=0):
""" Returns a sequence of locks. if 'killinvalids' is true,
invalid locks will be deleted"""
def wl_lockTokens(killinvalids=0):
""" Returns a sequence of lock tokens. if 'killinvalids' is true,
invalid locks will be deleted"""
def wl_hasLock(token, killinvalids=0):
""" Returns true if the lock identified by the token is attached
to the object. """
def wl_isLocked():
""" Returns true if 'self' is locked at all. If invalid locks
still exist, they should be deleted."""
def wl_setLock(locktoken, lock):
""" Store the LockItem, 'lock'. The locktoken will be used to fetch
and delete the lock. If the lock exists, this MUST
overwrite it if all of the values except for the 'timeout' on the
old and new lock are the same. """
def wl_getLock(locktoken):
""" Returns the locktoken identified by the locktokenuri """
def wl_delLock(locktoken):
""" Deletes the locktoken identified by the locktokenuri """
def wl_clearLocks():
""" Deletes ALL DAV locks on the object - should only be called
by lock management machinery. """
# XXX: might contain non-API methods and outdated comments; # XXX: might contain non-API methods and outdated comments;
......
import unittest import unittest
import Testing
import Zope2
Zope2.startup()
class TestCollection(unittest.TestCase): class TestCollection(unittest.TestCase):
...@@ -11,7 +8,7 @@ class TestCollection(unittest.TestCase): ...@@ -11,7 +8,7 @@ class TestCollection(unittest.TestCase):
from webdav.interfaces import IDAVCollection from webdav.interfaces import IDAVCollection
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IDAVCollection, Collection, 1) verifyClass(IDAVCollection, Collection)
def test_suite(): def test_suite():
......
import unittest import unittest
import Testing
import Zope2
Zope2.startup()
class TestLockNullResource(unittest.TestCase): class TestLockNullResource(unittest.TestCase):
...@@ -18,7 +15,7 @@ class TestLockNullResource(unittest.TestCase): ...@@ -18,7 +15,7 @@ class TestLockNullResource(unittest.TestCase):
from webdav.NullResource import LockNullResource from webdav.NullResource import LockNullResource
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IWriteLock, LockNullResource, 1) verifyClass(IWriteLock, LockNullResource)
class TestNullResource(unittest.TestCase): class TestNullResource(unittest.TestCase):
...@@ -35,7 +32,7 @@ class TestNullResource(unittest.TestCase): ...@@ -35,7 +32,7 @@ class TestNullResource(unittest.TestCase):
from webdav.NullResource import NullResource from webdav.NullResource import NullResource
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IWriteLock, NullResource, 1) verifyClass(IWriteLock, NullResource)
def test_suite(): def test_suite():
......
import unittest import unittest
import Testing
import Zope2
Zope2.startup()
class TestResource(unittest.TestCase): class TestResource(unittest.TestCase):
def test_z3interfaces(self): def test_z3interfaces(self):
from webdav.interfaces import IDAVResource from webdav.interfaces import IDAVResource
from webdav.interfaces import IWriteLock
from webdav.Resource import Resource from webdav.Resource import Resource
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
verifyClass(IDAVResource, Resource, 1) verifyClass(IDAVResource, Resource)
verifyClass(IWriteLock, Resource)
def test_suite(): def test_suite():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment