From e5edf9444c7528d779eaf68a5095a84266b64f9b Mon Sep 17 00:00:00 2001
From: Yoshinori Okuji <yo@nexedi.com>
Date: Tue, 12 Oct 2010 06:06:17 +0000
Subject: [PATCH] Re-apply r37787 with even more simplification.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@39042 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/CMFCategory/CategoryTool.py | 59 ++++++++++-------------------
 1 file changed, 20 insertions(+), 39 deletions(-)

diff --git a/product/CMFCategory/CategoryTool.py b/product/CMFCategory/CategoryTool.py
index ed835c8d8f..f59a4aa2f1 100644
--- a/product/CMFCategory/CategoryTool.py
+++ b/product/CMFCategory/CategoryTool.py
@@ -847,7 +847,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
     security.declareProtected( Permissions.AccessContentsInformation,
                                       'getSingleCategoryAcquiredMembershipList' )
     def getSingleCategoryAcquiredMembershipList(self, context, base_category, base=0,
-                                         spec=(), filter=None, acquired_object_dict = None, **kw ):
+                                         spec=(), filter=None, _acquired_object_set=None, **kw ):
       cache = getReadOnlyTransactionCache()
       if cache is not None:
         key = ('getSingleCategoryAcquiredMembershipList', context.getPhysicalPath(), base_category, base, spec,
@@ -859,7 +859,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
 
       result = self._getSingleCategoryAcquiredMembershipList(context, base_category, base=base,
                                                              spec=spec, filter=filter,
-                                                             acquired_object_dict = acquired_object_dict,
+                                                             _acquired_object_set=_acquired_object_set,
                                                              **kw)
       if cache is not None:
         cache[key] = result
@@ -892,8 +892,8 @@ class CategoryTool( UniqueObject, Folder, Base ):
     def _getSingleCategoryAcquiredMembershipList(self, context, base_category,
                                          base = 0, spec = (), filter = None,
                                          acquired_portal_type = (),
-                                         acquired_object_dict = None,
                                          checked_permission = None,
+                                         _acquired_object_set=None,
                                          **kw ):
       """
         Returns the acquired membership of the context for a single base category
@@ -911,9 +911,6 @@ class CategoryTool( UniqueObject, Folder, Base ):
         checked_permission        --    a string which defined the permission 
                                         to filter the object on
 
-        acquired_object_dict      --    this is the list of object used by acquisition, so
-                                        we can check if we already have used this object
-
         alt_base_category         --    an alternative base category if the first one fails
 
         acquisition_copy_value    --    if set to 1, the looked up value will be copied
@@ -924,6 +921,9 @@ class CategoryTool( UniqueObject, Folder, Base ):
 
         acquisition_sync_value    --    if set to 1, keep self and looked up value in sync
 
+        _acquired_object_set is a special, internal parameter to deal with
+        recursive calls on the same object.
+
       """
       #LOG("Get Acquired Category ",0,str((base_category, context,)))
       #LOG("Get Acquired Category acquired_object_dict: ",0,str(acquired_object_dict))
@@ -938,34 +938,15 @@ class CategoryTool( UniqueObject, Folder, Base ):
       if isinstance(acquired_portal_type, str):
         acquired_portal_type = [acquired_portal_type]
 
-      if acquired_object_dict is None:
-        acquired_object_dict = {} # Initial call may include filter, etc. - do not keep
+      if _acquired_object_set is None:
+        _acquired_object_set = set()
       else:
-        context_base_key = (tuple(context.getPhysicalPath()), base_category)
-        if context_base_key in acquired_object_dict:
-          acquired_object_dict = acquired_object_dict.copy()
-          type_set = acquired_object_dict[context_base_key].copy()
-          if spec is ():
-            if () in type_set:
-              return []
-            else:
-              type_set.add(())
-          else:
-            for pt in spec:
-              if pt in type_set:
-                return []
-              else:
-                type_set.add(pt)
-          acquired_object_dict[context_base_key] = type_set
-        else:
-          type_set = set()
-          if spec is ():
-            type_set.add(())
-          else:
-            for pt in spec:
-              type_set.add(pt)
-          acquired_object_dict = acquired_object_dict.copy()
-          acquired_object_dict[context_base_key] = type_set
+        uid = context.getUid()
+        key = (uid, base_category, tuple(spec))
+        if key in _acquired_object_set:
+          return []
+        _acquired_object_set = _acquired_object_set.copy()
+        _acquired_object_set.add(key)
 
       result = self.getSingleCategoryMembershipList( context, base_category, base=base,
                             spec=spec, filter=filter, **kw ) # Not acquired because this is the first try
@@ -993,7 +974,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
             #acquired_object_dict[my_acquisition_object_path] = 1
             if my_acquisition_object.portal_type in base_category_value.getAcquisitionPortalTypeList():
               new_result = self.getSingleCategoryAcquiredMembershipList(my_acquisition_object,
-                  base_category, spec=spec, filter=filter, portal_type=portal_type, base=base, acquired_object_dict=acquired_object_dict)
+                  base_category, spec=spec, filter=filter, portal_type=portal_type, base=base, _acquired_object_set=_acquired_object_set)
             else:
               new_result = []
             #if base_category_value.acquisition_mask_value:
@@ -1034,7 +1015,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
             my_acquisition_list = self.getSingleCategoryAcquiredMembershipList(context,
                         my_base_category,
                         portal_type=tuple(acquisition_pt),
-                        acquired_object_dict=acquired_object_dict)
+                        _acquired_object_set=_acquired_object_set)
             my_acquisition_object_list = []
             if my_acquisition_list:
               resolveCategory = self.resolveCategory
@@ -1070,7 +1051,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
                     new_result = self.getSingleCategoryAcquiredMembershipList(my_acquisition_object,
                         base_category, spec=spec, filter=filter, portal_type=portal_type, base=base,
                         acquired_portal_type=acquired_portal_type,
-                        acquired_object_dict=acquired_object_dict)
+                        _acquired_object_set=_acquired_object_set)
                   else:
                     #LOG("No recursive call ",0,str((spec, my_acquisition_object.portal_type)))
                     new_result = []
@@ -1109,7 +1090,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
           for base_category in fallback_base_category_list:
             # First get the category list
             category_list = getSingleCategoryAcquiredMembershipList( context, base_category, base=1,
-                                 spec=spec, filter=filter, acquired_object_dict=acquired_object_dict, **kw )
+                                 spec=spec, filter=filter, _acquired_object_set=_acquired_object_set, **kw )
             # Then convert it into value
             category_value_list = [resolveCategory(x) for x in category_list]
             # Then build the alternate category
@@ -1139,7 +1120,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
     security.declareProtected( Permissions.AccessContentsInformation,
                                                'getAcquiredCategoryMembershipList' )
     def getAcquiredCategoryMembershipList(self, context, base_category = None, base=1,
-                                          spec=(), filter=None, acquired_object_dict=None, **kw):
+                                          spec=(), filter=None, _acquired_object_set=None, **kw):
       """
         Returns all acquired category values
       """
@@ -1156,7 +1137,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
       getSingleCategoryAcquiredMembershipList = self.getSingleCategoryAcquiredMembershipList
       for base_category in base_category_list:
         extend(getSingleCategoryAcquiredMembershipList(context, base_category, base=base,
-                                    spec=spec, filter=filter, acquired_object_dict=acquired_object_dict, **kw ))
+                                    spec=spec, filter=filter, _acquired_object_set=_acquired_object_set, **kw ))
         #LOG('CT.getAcquiredCategoryMembershipList new result',0,result)
       return result
 
-- 
2.30.9