From e3f2a0a20d9cc93161e5fddbf98a5e707b079351 Mon Sep 17 00:00:00 2001
From: Ivan Tyagov <ivan@nexedi.com>
Date: Thu, 25 Oct 2012 09:08:45 +0300
Subject: [PATCH] Allow Cache Factory to contain Cache Bags which on its side
 can contain Cache Plugins. Unify in one function cache factory uid
 generation.

---
 product/ERP5Type/Core/CacheFactory.py | 12 +++++-
 product/ERP5Type/Tool/CacheTool.py    | 59 +++++++++++++++++----------
 2 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/product/ERP5Type/Core/CacheFactory.py b/product/ERP5Type/Core/CacheFactory.py
index 3a7a2efc07..f80fe74cb1 100644
--- a/product/ERP5Type/Core/CacheFactory.py
+++ b/product/ERP5Type/Core/CacheFactory.py
@@ -60,6 +60,16 @@ class CacheFactory(XMLObject):
                     , PropertySheet.CacheFactory
                     )
 
+  def getCacheUid(self):
+    """
+      Get a common Cache Factory / Cache Bag UID in this
+      case relative to portal_caches.
+      It's required to use relative url (i.e. mainly ID) due
+      to CachingMethod legacy.
+    """
+    relative_url = self.getRelativeUrl()
+    assert relative_url[:14] == 'portal_caches/'
+    return relative_url[14:]
 
   def getCachePluginList(self):
     """ get ordered list of installed cache plugins in ZODB """
@@ -71,7 +81,7 @@ class CacheFactory(XMLObject):
   security.declareProtected(Permissions.AccessContentsInformation, 'getRamCacheFactory')
   def getRamCacheFactory(self):
     """ Return RAM based cache factory """
-    cache_factory_name = self.getId()
+    cache_factory_name =  self.getCacheUid()
     cache_tool = self.portal_caches
     cache_factory = CachingMethod.factories.get(cache_factory_name)
     #XXX This conditional statement should be remove as soon as
diff --git a/product/ERP5Type/Tool/CacheTool.py b/product/ERP5Type/Tool/CacheTool.py
index 83965d4386..97fec600c1 100644
--- a/product/ERP5Type/Tool/CacheTool.py
+++ b/product/ERP5Type/Tool/CacheTool.py
@@ -66,38 +66,55 @@ class CacheTool(BaseTool):
   security.declareProtected(Permissions.AccessContentsInformation, 'getCacheFactoryList')
   def getCacheFactoryList(self):
     """ Return available cache factories """
+
+    def getRamCachePlugin(cp):
+      cp_meta_type = cp.meta_type
+      if cp_meta_type == 'ERP5 Ram Cache':
+        return RamCache()
+      if cp_meta_type == 'ERP5 Distributed Ram Cache':
+        ## even thougn we have such plugin in ZODB that doens't mean
+        ## we have corresponding memcache module installed
+        if getattr(cp, 'getSpecialiseValue', None) is not None:
+          memcached_plugin = cp.getSpecialiseValue()
+          if memcached_plugin is not None:
+            server = memcached_plugin.getUrlString('')
+            init_dict = {
+              'server': server,
+              'expiration_time': cf.getCacheDuration(),
+              'server_max_key_length': memcached_plugin.getServerMaxKeyLength(),
+              'server_max_value_length': memcached_plugin.getServerMaxValueLength(),
+              'key_prefix': getattr(self, 'erp5_site_global_id', '')}
+            return DistributedRamCache(init_dict)
+
     rd = {}
     for cf in self.objectValues(['ERP5 Cache Factory', 'ERP5 Cache Bag']):
-      cache_scope = cf.getId()
+      cache_scope = cf.getCacheUid()
       rd[cache_scope] = {}
       rd[cache_scope]['cache_plugins'] = []
       rd[cache_scope]['cache_params'] = {}
       for cp in cf.getCachePluginList():
-        cache_obj = None
-        cp_meta_type = cp.meta_type
-        if cp_meta_type == 'ERP5 Ram Cache':
-          cache_obj = RamCache()
-        elif cp_meta_type == 'ERP5 Distributed Ram Cache':
-          ## even thougn we have such plugin in ZODB that doens't mean
-          ## we have corresponding memcache module installed
-          cache_obj = None
-          if getattr(cp, 'getSpecialiseValue', None) is not None:
-            memcached_plugin = cp.getSpecialiseValue()
-            if memcached_plugin is not None:
-              server = memcached_plugin.getUrlString('')
-              init_dict = {
-                'server': server,
-                'expiration_time': cf.getCacheDuration(),
-                'server_max_key_length': memcached_plugin.getServerMaxKeyLength(),
-                'server_max_value_length': memcached_plugin.getServerMaxValueLength(),
-                'key_prefix': getattr(self, 'erp5_site_global_id', '')
-                            }
-              cache_obj = DistributedRamCache(init_dict)
+        cache_obj = getRamCachePlugin(cp)
         if cache_obj is not None:
           ## set cache expire check interval
           cache_obj.cache_expire_check_interval = cp.getCacheExpireCheckInterval()
           rd[cache_scope]['cache_plugins'].append(cache_obj)
           rd[cache_scope]['cache_params']['cache_duration'] = cf.getCacheDuration()
+
+      # support for cache bags which are like Cache Factory
+      # i.e. provide Cache Plugins
+      for cache_bag in cf.objectValues('ERP5 Cache Bag'):
+        cache_scope = cache_bag.getCacheUid()
+        rd[cache_scope] = {}
+        rd[cache_scope]['cache_plugins'] = []
+        rd[cache_scope]['cache_params'] = {}
+        for cp in cache_bag.getCachePluginList():
+          cache_obj = getRamCachePlugin(cp)
+          if cache_obj is not None:
+            ## set cache expire check interval
+            cache_obj.cache_expire_check_interval = cp.getCacheExpireCheckInterval()
+            rd[cache_scope]['cache_plugins'].append(cache_obj)
+            rd[cache_scope]['cache_params']['cache_duration'] = cf.getCacheDuration()
+
     return rd
 
   ##
-- 
2.30.9