Commit 8dcfdf4f authored by Vincent Pelletier's avatar Vincent Pelletier

ERP5Type.Core.Folder: Simplify proxy methods.

Also, clarify what exactly was the broken BTree marker value, fixing
isBTree accessor. Update associated tests.
parent 98635b88
...@@ -555,11 +555,20 @@ class FolderMixIn(ExtensionClass.Base): ...@@ -555,11 +555,20 @@ class FolderMixIn(ExtensionClass.Base):
parsed_given_url.netloc == parsed_document_url.netloc and \ parsed_given_url.netloc == parsed_document_url.netloc and \
(parsed_given_url.path + '/').startswith((parsed_document_url.path + '/')) (parsed_given_url.path + '/').startswith((parsed_document_url.path + '/'))
InitializeClass(FolderMixIn)
OFS_HANDLER = 0 OFS_HANDLER = 0
BTREE_HANDLER = 1 BTREE_HANDLER = 1
HBTREE_HANDLER = 2 HBTREE_HANDLER = 2
_BTREE_PROPERTY_ID = '_tree'
InitializeClass(FolderMixIn) _HBTREE_PROPERTY_ID = '_htree'
_HANDLER_LIST = (
None,
(_BTREE_PROPERTY_ID, BTreeFolder2Base.__init__, CMFBTreeFolder),
(_HBTREE_PROPERTY_ID, HBTreeFolder2Base.__init__, CMFHBTreeFolder),
)
# Bad value, accidentally put everywhere long ago
_BROKEN_BTREE_HANDLER = 'CMFBTreeFolderHandler'
class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
""" """
...@@ -640,13 +649,20 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): ...@@ -640,13 +649,20 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
""" Create a new content """ """ Create a new content """
# Create data structure if none present # Create data structure if none present
return FolderMixIn.newContent(self, *args, **kw) return FolderMixIn.newContent(self, *args, **kw)
def _getFolderHandlerData(self):
# Internal API working around bogus _folder_handler values.
folder_handler = self._folder_handler
if folder_handler == _BROKEN_BTREE_HANDLER:
folder_handler = BTREE_HANDLER
return _HANDLER_LIST[folder_handler]
security.declareProtected(Permissions.AccessContentsInformation, 'isBTree') security.declareProtected(Permissions.AccessContentsInformation, 'isBTree')
def isBTree(self): def isBTree(self):
""" """
Tell if we are a BTree Tell if we are a BTree
""" """
return self._folder_handler == BTREE_HANDLER return self._folder_handler in (BTREE_HANDLER, _BROKEN_BTREE_HANDLER)
security.declareProtected(Permissions.AccessContentsInformation, 'isHBTree') security.declareProtected(Permissions.AccessContentsInformation, 'isHBTree')
def isHBTree(self): def isHBTree(self):
...@@ -756,44 +772,28 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): ...@@ -756,44 +772,28 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
# We use this method instead of plugin because it make # We use this method instead of plugin because it make
# less function call and thus Folder faster # less function call and thus Folder faster
def _initBTrees(self): def _initBTrees(self):
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2]._initBTrees(self)
return CMFHBTreeFolder._initBTrees(self)
else:
return CMFBTreeFolder._initBTrees(self)
def hashId(self, id): def hashId(self, id):
"""Return a hash of id """Return a hash of id
""" """
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2].hashId(self, id)
return CMFHBTreeFolder.hashId(self, id)
else:
return CMFBTreeFolder.hashId(self, id)
def _populateFromFolder(self, source): def _populateFromFolder(self, source):
"""Fill this folder with the contents of another folder. """Fill this folder with the contents of another folder.
""" """
if self._folder_handler == HBTREE_HANDLER: property_id, init, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
HBTreeFolder2Base.__init__(self, id) init(self, self.id)
return CMFHBTreeFolder._populateFromFolder(self, source) return folder._populateFromFolder(self, source)
else:
if self._tree is None:
BTreeFolder2Base.__init__(self, id)
return CMFBTreeFolder._populateFromFolder(self, source)
def manage_fixCount(self): def manage_fixCount(self):
"""Calls self._fixCount() and reports the result as text. """Calls self._fixCount() and reports the result as text.
""" """
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2].manage_fixCount(self)
return CMFHBTreeFolder.manage_fixCount(self)
else:
return CMFBTreeFolder.manage_fixCount(self)
def _fixCount(self): def _fixCount(self):
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2]._fixCount(self)
return CMFHBTreeFolder._fixCount(self)
else:
return CMFBTreeFolder._fixCount(self)
def _fixFolderHandler(self): def _fixFolderHandler(self):
"""Fixes _folder_handler if it is a string """Fixes _folder_handler if it is a string
...@@ -813,133 +813,82 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): ...@@ -813,133 +813,82 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def manage_cleanup(self): def manage_cleanup(self):
"""Calls self._cleanup() and reports the result as text. """Calls self._cleanup() and reports the result as text.
""" """
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return 1 return 1
else: return folder.manage_cleanup(self)
return CMFHBTreeFolder.manage_cleanup(self)
else:
if self._tree is None:
return 1
else:
return CMFBTreeFolder.manage_cleanup(self)
def _cleanup(self): def _cleanup(self):
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return 1 return 1
else: return folder._cleanup(self)
return CMFHBTreeFolder._cleanup(self)
else:
if self._tree is None:
return 1
else:
return CMFBTreeFolder._cleanup(self)
def _getOb(self, id, *args, **kw): def _getOb(self, id, *args, **kw):
""" """
Return the named object from the folder. Return the named object from the folder.
""" """
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
if len(args): if args:
return args[0] return args[0]
elif kw.has_key("default"): elif 'default' in kw:
return kw["default"] return kw['default']
else: else:
raise KeyError, id raise KeyError(id)
return CMFHBTreeFolder._getOb(self, id, *args, **kw) return folder._getOb(self, id, *args, **kw)
else:
if self._tree is None:
if len(args):
return args[0]
elif kw.has_key("default"):
return kw["default"]
else:
raise KeyError, id
return CMFBTreeFolder._getOb(self, id, *args, **kw)
def _setOb(self, id, object): def _setOb(self, id, object):
"""Store the named object in the folder. """Store the named object in the folder.
""" """
if self._folder_handler == HBTREE_HANDLER: property_id, init, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
HBTreeFolder2Base.__init__(self, self.id) init(self, self.id)
return CMFHBTreeFolder._setOb(self, id, object) return folder._setOb(self, id, object)
else:
if self._tree is None:
BTreeFolder2Base.__init__(self, self.id)
return CMFBTreeFolder._setOb(self, id, object)
def _delOb(self, id): def _delOb(self, id):
"""Remove the named object from the folder. """Remove the named object from the folder.
""" """
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2]._delOb(self, id)
return CMFHBTreeFolder._delOb(self, id)
else:
return CMFBTreeFolder._delOb(self, id)
def getBatchObjectListing(self, REQUEST=None): def getBatchObjectListing(self, REQUEST=None):
"""Return a structure for a page template to show the list of objects. """Return a structure for a page template to show the list of objects.
""" """
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2].getBatchObjectListing(self, REQUEST)
return CMFHBTreeFolder.getBatchObjectListing(self, REQUEST)
else:
return CMFBTreeFolder.getBatchObjectListing(self, REQUEST)
def manage_object_workspace(self, ids=(), REQUEST=None): def manage_object_workspace(self, ids=(), REQUEST=None):
'''Redirects to the workspace of the first object in '''Redirects to the workspace of the first object in
the list.''' the list.'''
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2].manage_object_workspace(self, ids, REQUEST)
return CMFHBTreeFolder.manage_object_workspace(self, ids, REQUEST)
else:
return CMFBTreeFolder.manage_object_workspace(self, ids, REQUEST)
def manage_main(self, *args, **kw): def manage_main(self, *args, **kw):
''' List content.''' ''' List content.'''
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2].manage_main.__of__(self)(self, *args, **kw)
return CMFHBTreeFolder.manage_main.__of__(self)(self, *args, **kw)
else:
return CMFBTreeFolder.manage_main.__of__(self)(self, *args, **kw)
def tpValues(self): def tpValues(self):
"""Ensures the items don't show up in the left pane. """Ensures the items don't show up in the left pane.
""" """
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2].tpValues(self)
return CMFHBTreeFolder.tpValues(self)
else:
return CMFBTreeFolder.tpValues(self)
def objectCount(self): def objectCount(self):
"""Returns the number of items in the folder.""" """Returns the number of items in the folder."""
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return 0 return 0
return CMFHBTreeFolder.objectCount(self) return folder.objectCount(self)
else:
if self._tree is None:
return 0
return CMFBTreeFolder.objectCount(self)
def has_key(self, id): def has_key(self, id):
"""Indicates whether the folder has an item by ID. """Indicates whether the folder has an item by ID.
""" """
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return False return False
return CMFHBTreeFolder.has_key(self, id) return folder.has_key(self, id)
else:
if self._tree is None:
return False
return CMFBTreeFolder.has_key(self, id)
def getTreeIdList(self, htree=None): def getTreeIdList(self, htree=None):
""" recursively build a list of btree ids """ recursively build a list of btree ids
""" """
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2].getTreeIdList(self, htree)
return CMFHBTreeFolder.getTreeIdList(self, htree)
else:
return CMFBTreeFolder.getTreeIdList(self, htree)
def objectIds(self, spec=None, **kw): def objectIds(self, spec=None, **kw):
if self._folder_handler == HBTREE_HANDLER: if self._folder_handler == HBTREE_HANDLER:
...@@ -948,12 +897,11 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): ...@@ -948,12 +897,11 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
assert spec is None assert spec is None
if kw.has_key("base_id"): if kw.has_key("base_id"):
return CMFHBTreeFolder.objectIds(self, base_id=kw["base_id"]) return CMFHBTreeFolder.objectIds(self, base_id=kw["base_id"])
else: return CMFHBTreeFolder.objectIds(self)
return CMFHBTreeFolder.objectIds(self) property_id, _, folder = self._getFolderHandlerData()
else: if getattr(self, property_id) is None:
if self._tree is None: return []
return [] return folder.objectIds(self, spec)
return CMFBTreeFolder.objectIds(self, spec)
def objectItems(self, spec=None, **kw): def objectItems(self, spec=None, **kw):
if self._folder_handler == HBTREE_HANDLER: if self._folder_handler == HBTREE_HANDLER:
...@@ -962,47 +910,32 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): ...@@ -962,47 +910,32 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
assert spec is None assert spec is None
if kw.has_key("base_id"): if kw.has_key("base_id"):
return CMFHBTreeFolder.objectItems(self, base_id=kw["base_id"]) return CMFHBTreeFolder.objectItems(self, base_id=kw["base_id"])
else: return CMFHBTreeFolder.objectItems(self)
return CMFHBTreeFolder.objectItems(self) property_id, _, folder = self._getFolderHandlerData()
else: if getattr(self, property_id) is None:
if self._tree is None: return []
return [] return folder.objectItems(self, spec)
return CMFBTreeFolder.objectItems(self, spec)
def objectIds_d(self, t=None): def objectIds_d(self, t=None):
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return {} return {}
return CMFHBTreeFolder.objectIds_d(self, t) return folder.objectIds_d(self, t)
else:
if self._tree is None:
return {}
return CMFBTreeFolder.objectIds_d(self, t)
def _checkId(self, id, allow_dup=0): def _checkId(self, id, allow_dup=0):
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2]._checkId(self, id, allow_dup)
return CMFHBTreeFolder._checkId(self, id, allow_dup)
else:
return CMFBTreeFolder._checkId(self, id, allow_dup)
def _setObject(self, *args, **kw): def _setObject(self, *args, **kw):
if self._folder_handler == HBTREE_HANDLER: property_id, init, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
HBTreeFolder2Base.__init__(self, self.id) init(self, self.id)
return CMFHBTreeFolder._setObject(self, *args, **kw) return folder._setObject(self, *args, **kw)
else:
if self._tree is None:
BTreeFolder2Base.__init__(self, self.id)
return CMFBTreeFolder._setObject(self, *args, **kw)
def get(self, id, default=None): def get(self, id, default=None):
""" """
Return the named object from the folder. Return the named object from the folder.
""" """
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2].get(self, id, default)
return CMFHBTreeFolder.get(self, id, default)
else:
return CMFBTreeFolder.get(self, id, default)
def generateId(self, prefix='item', suffix='', rand_ceiling=999999999): def generateId(self, prefix='item', suffix='', rand_ceiling=999999999):
"""Returns an ID not used yet by this folder. """Returns an ID not used yet by this folder.
...@@ -1011,77 +944,54 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): ...@@ -1011,77 +944,54 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
The IDs are sequential to optimize access to objects The IDs are sequential to optimize access to objects
that are likely to have some relation. that are likely to have some relation.
""" """
if self._folder_handler == HBTREE_HANDLER: return self._getFolderHandlerData()[2].generateId(self, prefix, suffix, rand_ceiling)
return CMFHBTreeFolder.generateId(self, prefix, suffix, rand_ceiling)
else:
return CMFBTreeFolder.generateId(self, prefix, suffix, rand_ceiling)
def __getattr__(self, name): def __getattr__(self, name):
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
return CMFHBTreeFolder.__getattr__(self, name) if getattr(self, property_id) is None:
else: raise AttributeError(name)
if self._tree is None: return folder.__getattr__(self, name)
raise AttributeError, name
return CMFBTreeFolder.__getattr__(self, name)
def __len__(self): def __len__(self):
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return 0 return 0
return CMFHBTreeFolder.__len__(self) return folder.__len__(self)
else:
if self._tree is None:
return 0
return CMFBTreeFolder.__len__(self)
def keys(self, *args, **kw): def keys(self, *args, **kw):
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return [] return []
return CMFHBTreeFolder.keys(self, *args, **kw) return folder.keys(self, *args, **kw)
else:
if self._tree is None:
return []
return CMFBTreeFolder.keys(self, *args, **kw)
def values(self, *args, **kw): def values(self, *args, **kw):
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return [] return []
return CMFHBTreeFolder.values(self, *args, **kw) return folder.values(self, *args, **kw)
else:
if self._tree is None:
return []
return CMFBTreeFolder.values(self, *args, **kw)
def items(self, *args, **kw): def items(self, *args, **kw):
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return [] return []
return CMFHBTreeFolder.items(self, *args, **kw) return folder.items(self, *args, **kw)
else:
if self._tree is None:
return []
return CMFBTreeFolder.items(self, *args, **kw)
def iteritems(self, *args, **kw): def iteritems(self, *args, **kw):
if self._folder_handler == HBTREE_HANDLER: if self._folder_handler == HBTREE_HANDLER:
result = CMFHBTreeFolder._htree_iteritems(self, *args, **kw) result = CMFHBTreeFolder._htree_iteritems(self, *args, **kw)
else: elif self.isBTree():
if self._tree is None: if self._tree is None:
return () return ()
result = self._tree.iteritems(*args, **kw) result = self._tree.iteritems(*args, **kw)
else:
raise NotImplementedError
return NullIter(((x, y.__of__(self)) for x, y in result)) return NullIter(((x, y.__of__(self)) for x, y in result))
def hasObject(self, id): def hasObject(self, id):
if self._folder_handler == HBTREE_HANDLER: property_id, _, folder = self._getFolderHandlerData()
if self._htree is None: if getattr(self, property_id) is None:
return False return False
return CMFHBTreeFolder.hasObject(self, id) return folder.hasObject(self, id)
else:
if self._tree is None:
return False
return CMFBTreeFolder.hasObject(self, id)
# Work around for the performance regression introduced in Zope 2.12.23. # Work around for the performance regression introduced in Zope 2.12.23.
# Otherwise, we use superclass' __contains__ implementation, which uses # Otherwise, we use superclass' __contains__ implementation, which uses
...@@ -1512,11 +1422,7 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): ...@@ -1512,11 +1422,7 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
# (no docstring to prevent publishing) # (no docstring to prevent publishing)
if meta_type is not None: if meta_type is not None:
spec = meta_type spec = meta_type
if self._folder_handler == BTREE_HANDLER: if self._folder_handler == HBTREE_HANDLER:
if self._tree is None:
return []
object_list = CMFBTreeFolder.objectValues(self, spec=spec)
elif self._folder_handler == HBTREE_HANDLER:
if self._htree is None: if self._htree is None:
return [] return []
assert spec is None assert spec is None
...@@ -1524,6 +1430,10 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): ...@@ -1524,6 +1430,10 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
object_list = CMFHBTreeFolder.objectValues(self, base_id=kw['base_id']) object_list = CMFHBTreeFolder.objectValues(self, base_id=kw['base_id'])
else: else:
object_list = CMFHBTreeFolder.objectValues(self) object_list = CMFHBTreeFolder.objectValues(self)
elif self.isBTree():
if self._tree is None:
return []
object_list = CMFBTreeFolder.objectValues(self, spec=spec)
else: else:
object_list = map(self._getOb, self.objectIds(spec)) object_list = map(self._getOb, self.objectIds(spec))
if portal_type is not None: if portal_type is not None:
......
...@@ -443,10 +443,9 @@ class TestFolderMigration(ERP5TypeTestCase, LogInterceptor): ...@@ -443,10 +443,9 @@ class TestFolderMigration(ERP5TypeTestCase, LogInterceptor):
self.assertEqual(self.folder.isBTree(), True) self.assertEqual(self.folder.isBTree(), True)
self.assertEqual(self.folder.isHBTree(), False) self.assertEqual(self.folder.isHBTree(), False)
setattr(self.folder,'_folder_handler','VeryWrongHandler') self.folder._folder_handler = 'CMFBTreeFolderHandler'
self.tic() self.tic()
self.assertEqual(self.folder.isBTree(), False)
self.assertEqual(self.folder.isHBTree(), False) self.assertEqual(self.folder.isHBTree(), False)
self.assertEqual(self.folder._fixFolderHandler(), True) self.assertEqual(self.folder._fixFolderHandler(), True)
...@@ -465,10 +464,9 @@ class TestFolderMigration(ERP5TypeTestCase, LogInterceptor): ...@@ -465,10 +464,9 @@ class TestFolderMigration(ERP5TypeTestCase, LogInterceptor):
self.assertEqual(self.folder.isBTree(), True) self.assertEqual(self.folder.isBTree(), True)
self.assertEqual(self.folder.isHBTree(), False) self.assertEqual(self.folder.isHBTree(), False)
setattr(self.folder,'_folder_handler','VeryWrongHandler') self.folder._folder_handler = 'CMFBTreeFolderHandler'
self.tic() self.tic()
self.assertEqual(self.folder.isBTree(), False)
self.assertEqual(self.folder.isHBTree(), False) self.assertEqual(self.folder.isHBTree(), False)
self.folder.migrateToHBTree() self.folder.migrateToHBTree()
......
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