[Zope-Checkins] CVS: Zope/lib/python/OFS - Cache.py:1.10.68.1.10.1

Tres Seaver tseaver at zope.com
Wed May 19 18:54:19 EDT 2004


Update of /cvs-repository/Zope/lib/python/OFS
In directory cvs.zope.org:/tmp/cvs-serv21096/lib/python/OFS

Modified Files:
      Tag: tseaver-collector_911-branch
	Cache.py 
Log Message:
 - Initial pass at merging leper's changes from Collector #911.


=== Zope/lib/python/OFS/Cache.py 1.10.68.1 => 1.10.68.1.10.1 ===
--- Zope/lib/python/OFS/Cache.py:1.10.68.1	Mon Nov 17 17:34:07 2003
+++ Zope/lib/python/OFS/Cache.py	Wed May 19 18:53:47 2004
@@ -10,35 +10,37 @@
 # FOR A PARTICULAR PURPOSE
 #
 ##############################################################################
-__doc__="""Cacheable object and cache management base classes.
-
-$Id$"""
-
-__version__='$Revision$'[11:-2]
+"""Cacheable object and cache management base classes.
 
+$Id$
+"""
 import time, sys
-import Globals
+
 from Globals import DTMLFile
+from Globals import InitializeClass
 from Acquisition import aq_get, aq_acquire, aq_inner, aq_parent, aq_base
 from zLOG import LOG, WARNING
 from AccessControl import getSecurityManager
+from AccessControl import ClassSecurityInfo
 from AccessControl.Role import _isBeingUsedAsAMethod
 from AccessControl import Unauthorized
 
+from AccessControl.Permissions import \
+    access_contents_information as AccessContentsInformation
+from AccessControl.Permissions import \
+    view_management_screens as ViewManagementScreens
+ChangeCacheSettings = 'Change cache settings'
+
 ZCM_MANAGERS = '__ZCacheManager_ids__'
 
-ViewManagementScreensPermission = 'View management screens'
-ChangeCacheSettingsPermission = 'Change cache settings'
 
 
 def isCacheable(ob):
     return getattr(aq_base(ob), '_isCacheable', 0)
 
 def managersExist(ob):
-    # Returns 1 if any CacheManagers exist in the context of ob.
-    if aq_get(ob, ZCM_MANAGERS, None, 1):
-        return 1
-    return 0
+    # Returns True if any CacheManagers exist in the context of ob.
+    return bool(aq_get(ob, ZCM_MANAGERS, None, 1))
 
 def filterCacheTab(ob):
     if _isBeingUsedAsAMethod(ob):
@@ -49,24 +51,19 @@
         return managersExist(ob)
 
 def filterCacheManagers(orig, container, name, value, extra):
-    '''
-    This is a filter method for aq_acquire.
-    It causes objects to be found only if they are
-    in the list of cache managers.
-    '''
-    if (hasattr(aq_base(container), ZCM_MANAGERS) and
-        name in getattr(container, ZCM_MANAGERS)):
-        return 1
-    return 0
+    # Filter method for aq_acquire: pass only objects which are in the
+    # list of cache managers.
+    managers = getattr(aq_base(container), ZCM_MANAGERS, ())
+    return name in managers
 
 def getVerifiedManagerIds(container):
-    '''
-    Gets the list of cache managers in a container, verifying each one.
-    '''
+    """List the cache managers in a container, verifying each one.
+    """
     ids = getattr(container, ZCM_MANAGERS, ())
     rval = []
     for id in ids:
-        if getattr(getattr(container, id, None), '_isCacheManager', 0):
+        manager = getattr(container, id, None)
+        if getattr(manager, '_isCacheManager', 0):
             rval.append(id)
     return tuple(rval)
 
@@ -76,11 +73,22 @@
 # that.
 manager_timestamp = 0
 
+class CacheException(Exception):
+    """Exception type raised when a recoverable problem is encountered
+    """
+    # Subclass and use me in your cache implementations!
 
-class Cacheable:
-    '''Mix-in for cacheable objects.
-    '''
 
+class Cacheable:
+    """Mix-in for cacheable objects.
+    """
+    security = ClassSecurityInfo()
+    security.setPermissionDefault(ChangeCacheSettings, ('Manager',))
+    __manager_id = None
+    __enabled = 1
+    _v_ZCacheable_cache = None
+    _v_ZCacheable_manager_timestamp = 0
+    _isCacheable = 1
     manage_options = ({
         'label':'Cache',
         'action':'ZCacheable_manage',
@@ -88,33 +96,13 @@
         'help':('OFSP','Cacheable-properties.stx'),
         },)
 
-    __ac_permissions__ = (
-        (ViewManagementScreensPermission,
-         ('ZCacheable_manage',
-          'ZCacheable_invalidate',
-          'ZCacheable_isMethod',
-          'ZCacheable_enabled',
-          'ZCacheable_getManagerId',
-          'ZCacheable_getManagerIds',
-          'ZCacheable_configHTML',
-          )),
-        (ChangeCacheSettingsPermission,
-         ('ZCacheable_setManagerId',
-          'ZCacheable_setEnabled',
-          ), ('Manager',)),
-        )
-
+    security.declareProtected(ViewManagementScreens, "ZCacheable_manage")
     ZCacheable_manage = DTMLFile('dtml/cacheable', globals())
 
-    _v_ZCacheable_cache = None
-    _v_ZCacheable_manager_timestamp = 0
-    __manager_id = None
-    __enabled = 1
-    _isCacheable = 1
-
-    ZCacheable_getManager__roles__ = ()
+    security.declarePrivate("ZCacheable_getManager")
     def ZCacheable_getManager(self):
-        '''Returns the currently associated cache manager.'''
+        """Return the currently associated cache manager.
+        """
         manager_id = self.__manager_id
         if manager_id is None:
             return None
@@ -125,10 +113,10 @@
         except AttributeError:
             return None
 
-    ZCacheable_getCache__roles__ = ()
+    security.declarePrivate("ZCacheable_getCache")
     def ZCacheable_getCache(self):
-        '''Gets the cache associated with this object.
-        '''
+        """Get the cache associated with this object.
+        """
         if self.__manager_id is None:
             return None
         c = self._v_ZCacheable_cache
@@ -146,28 +134,30 @@
         self._v_ZCacheable_manager_timestamp = manager_timestamp
         return c
 
-    ZCacheable_isCachingEnabled__roles__ = ()
+    security.declarePrivate("ZCacheable_isCachingEnabled")
     def ZCacheable_isCachingEnabled(self):
-        '''
-        Returns true only if associated with a cache manager and
-        caching of this method is enabled.
-        '''
+        """Is caching enabled / possible?
+        
+        o Return true only if associated with a cache manager and
+          caching of this method is enabled.
+        """
         return self.__enabled and self.ZCacheable_getCache()
 
+    security.declareProtected(ViewManagementScreens, "ZCacheable_isAMethod")
     def ZCacheable_isAMethod(self):
-        '''
-        Returns 1 when this object is a ZClass method.
-        '''
+        """Is this object is a ZClass method?
+        """
         m = _isBeingUsedAsAMethod(self)
         return m
 
-    ZCacheable_getObAndView__roles__ = ()
+    security.declarePrivate("ZCacheable_getObAndView")
     def ZCacheable_getObAndView(self, view_name):
-        """
-        If this object is a method of a ZClass and we're working
-        with the primary view, uses the ZClass instance as ob
-        and our own ID as the view_name.  Otherwise returns
-        self and view_name unchanged.
+        """Normalize ob, view in the presence of ZClasses.
+
+        o If this object is a method of a ZClass and we're working
+          with the primary view, uses the ZClass instance as ob
+          and our own ID as the view_name.  Otherwise returns
+          self and view_name unchanged.
         """
         ob = self
         if not view_name and self.ZCacheable_isAMethod():
@@ -181,13 +171,15 @@
                 ob = self
         return ob, view_name
 
-    ZCacheable_get__roles__ = ()
+    security.declarePrivate("ZCacheable_get")
     def ZCacheable_get(self, view_name='', keywords=None,
                        mtime_func=None, default=None):
-        '''Retrieves the cached view for the object under the
-        conditions specified by keywords. If the value is
-        not yet cached, returns the default.
-        '''
+        """Retrieve the cached view for the object
+        
+        o Retrieval conforms to the conditions specified by keywords.
+        
+        o If the value is not yet cached, return the default.
+        """
         c = self.ZCacheable_getCache()
         if c is not None and self.__enabled:
             ob, view_name = self.ZCacheable_getObAndView(view_name)
@@ -195,33 +187,39 @@
                 val = c.ZCache_get(ob, view_name, keywords,
                                    mtime_func, default)
                 return val
-            except:
-                LOG('Cache', WARNING, 'ZCache_get() exception',
-                    error=sys.exc_info())
-                return default
+            except CacheException, e:
+                LOG('Cache', WARNING, e)
         return default
 
-    ZCacheable_set__roles__ = ()
+    security.declarePrivate("ZCacheable_set")
     def ZCacheable_set(self, data, view_name='', keywords=None,
                        mtime_func=None):
-        '''Cacheable views should call this method after generating
-        cacheable results. The data argument can be of any Python type.
-        '''
+        """Store a cached rendering of 'self' via 'view_name'.
+        
+        o Cacheable views should call this method after generating
+          cacheable results.
+          
+        o The 'data' argument can be of any Python type.
+        """
         c = self.ZCacheable_getCache()
         if c is not None and self.__enabled:
             ob, view_name = self.ZCacheable_getObAndView(view_name)
             try:
                 c.ZCache_set(ob, data, view_name, keywords,
                              mtime_func)
-            except:
-                LOG('Cache', WARNING, 'ZCache_set() exception',
-                    error=sys.exc_info())
+            except CacheException, e:
+                LOG('Cache', WARNING, e)
 
+    security.declareProtected(ViewManagementScreens, "ZCacheable_invalidate")
     def ZCacheable_invalidate(self, view_name='', REQUEST=None):
-        '''Called after a cacheable object is edited. Causes all
-        cache entries that apply to the view_name to be removed.
-        Returns a status message.
-        '''
+        """Invalidate any cached representations of 'self' via 'view_name'.
+        
+        o Called after a cacheable object is edited.
+        
+        o Remove all cache entries that apply to 'view_name'.
+
+        o Return a status message.
+        """
         c = self.ZCacheable_getCache()
         if c is not None:
             ob, view_name = self.ZCacheable_getObAndView(view_name)
@@ -229,14 +227,9 @@
                 message = c.ZCache_invalidate(ob)
                 if not message:
                     message = 'Invalidated.'
-            except:
-                exc = sys.exc_info()
-                try:
-                    LOG('Cache', WARNING, 'ZCache_invalidate() exception',
-                        error=exc)
-                    message = 'An exception occurred: %s: %s' % exc[:2]
-                finally:
-                    exc = None
+            except CacheException, e:
+                message = 'An exception occurred: %s' % e
+                LOG('Cache', WARNING, e)
         else:
             message = 'This object is not associated with a cache manager.'
         if REQUEST is not None:
@@ -246,9 +239,10 @@
         else:
             return message
 
-    ZCacheable_getModTime__roles__=()
+    security.declarePrivate("ZCacheable_getModTime")
     def ZCacheable_getModTime(self, mtime_func=None):
-        '''Returns the highest of the last mod times.'''
+        """Returns the highest of the last mod times for 'self'.
+        """
         # Based on:
         #   mtime_func
         #   self.mtime
@@ -274,20 +268,27 @@
                 mtime = max(getattr(klass, '_p_mtime', mtime), mtime)
         return mtime
 
+    security.declareProtected(ViewManagementScreens, "ZCacheable_getManagerId")
     def ZCacheable_getManagerId(self):
-        '''Returns the id of the current ZCacheManager.'''
+        """Return the id of the current ZCacheManager.
+        """
         return self.__manager_id
 
+    security.declarePrivate("ZCacheable_getManagerURL")
     def ZCacheable_getManagerURL(self):
-        '''Returns the URL of the current ZCacheManager.'''
+        """Return the URL of the current ZCacheManager.
+        """
         manager = self.ZCacheable_getManager()
         if manager is not None:
             return manager.absolute_url()
         return None
 
+    security.declareProtected(ViewManagementScreens, "ZCacheable_getManagerIds")
     def ZCacheable_getManagerIds(self):
-        '''Returns a list of mappings containing the id and title
-        of the available ZCacheManagers.'''
+        """Return a list of mappings describing the available ZCacheManagers.
+        
+        o Keys in the mappings: 'id' and 'title'
+        """
         rval = []
         ob = self
         used_ids = {}
@@ -306,8 +307,12 @@
             ob = aq_parent(aq_inner(ob))
         return tuple(rval)
 
+    security.declareProtected(ChangeCacheSettings, "ZCacheable_setManagerId")
     def ZCacheable_setManagerId(self, manager_id, REQUEST=None):
-        '''Changes the manager_id for this object.'''
+        """Assoctate 'self' with a new ZCacheManager.
+        
+        o The new manager is identified via 'manager_id'.
+        """
         self.ZCacheable_invalidate()
         if not manager_id:
             # User requested disassociation
@@ -322,86 +327,89 @@
                 self, REQUEST, management_view='Cache',
                 manage_tabs_message='Cache settings changed.')
 
+    security.declareProtected(ViewManagementScreens, "ZCacheable_enabled")
     def ZCacheable_enabled(self):
-        '''Returns true if caching is enabled for this object
-        or method.'''
+        """Is caching enabled for this object or method?
+        """
         return self.__enabled
 
+    security.declareProtected(ChangeCacheSettings, "ZCacheable_setEnabled")
     def ZCacheable_setEnabled(self, enabled=0, REQUEST=None):
-        '''Changes the enabled flag. Normally used only when
-        setting up cacheable ZClass methods.'''
+        """Update the enabled flag.
+        
+        o Normally used only when setting up cacheable ZClass methods.
+        """
         self.__enabled = enabled and 1 or 0
         if REQUEST is not None:
             return self.ZCacheable_manage(
                 self, REQUEST, management_view='Cache',
                 manage_tabs_message='Cache settings changed.')
 
+    security.declareProtected(ViewManagementScreens, "ZCacheable_configHTML")
     def ZCacheable_configHTML(self):
-        '''Override to provide configuration of caching
-        behavior that can only be specific to the cacheable object.
-        '''
+        """Hook to permit subclasses to add UI for caching behavior.
+        
+        o Subclasses may override to provide configuration of caching
+          behavior that can only be specific to the cacheable object.
+        """
         return ''
 
 
-Globals.default__class_init__(Cacheable)
+InitializeClass(Cacheable)
 
 
 def findCacheables(ob, manager_id, require_assoc, subfolders,
                    meta_types, rval, path):
-    '''
-    Used by the CacheManager UI.  Recursive.  Similar to the Zope
-    "Find" function.  Finds all Cacheable objects in a hierarchy.
-    '''
-    try:
-        if meta_types:
-            subobs = ob.objectValues(meta_types)
-        else:
-            subobs = ob.objectValues()
-        sm = getSecurityManager()
+    # Perform a recursive search for cacheable objects.
+    #
+    # o Used by the CacheManager UI. 
+    #
+    # o Similar to the Zope "Find" function.
+    #
+    sm = getSecurityManager()
+    if not sm.checkPermission(AccessContentsInformation, ob):
+        return
+
+    ov = getattr(ob, 'objectValues', None)
+    if ov is None:
+        return
+
+    if meta_types:
+        subobs = ov(meta_types)
+    else:
+        subobs = ov()
 
-        # Add to the list of cacheable objects.
-        for subob in subobs:
-            if not isCacheable(subob):
-                continue
-            associated = (subob.ZCacheable_getManagerId() == manager_id)
-            if require_assoc and not associated:
-                continue
-            if not sm.checkPermission('Change cache settings', subob):
-                continue
+    # Add to the list of cacheable objects.
+    for subob in filter(isCacheable, subobs):
+        associated = (subob.ZCacheable_getManagerId() == manager_id)
+        if require_assoc and not associated:
+            continue
+        if not sm.checkPermission(ChangeCacheSettings, subob):
+            continue
+        subpath = path + (subob.getId(),)
+        icon = getattr(aq_base(subob), 'icon', '')
+        info = {
+            'sortkey': subpath,
+            'path': '/'.join(subpath),
+            'title': getattr(aq_base(subob), 'title', ''),
+            'icon': icon,
+            'associated': associated,}
+        rval.append(info)
+
+    # Visit subfolders.
+    if subfolders:
+        for subob in ov():
             subpath = path + (subob.getId(),)
-            icon = getattr(aq_base(subob), 'icon', '')
-            info = {
-                'sortkey': subpath,
-                'path': '/'.join(subpath),
-                'title': getattr(aq_base(subob), 'title', ''),
-                'icon': icon,
-                'associated': associated,}
-            rval.append(info)
-
-        # Visit subfolders.
-        if subfolders:
-            if meta_types:
-                subobs = ob.objectValues()
-            for subob in subobs:
-                subpath = path + (subob.getId(),)
-                if hasattr(aq_base(subob), 'objectValues'):
-                    if sm.checkPermission(
-                        'Access contents information', subob):
-                        findCacheables(
-                            subob, manager_id, require_assoc,
-                            subfolders, meta_types, rval, subpath)
-    except:
-        # Ignore exceptions.
-        import traceback
-        traceback.print_exc()
+            findCacheables(subob, manager_id, require_assoc,
+                           subfolders, meta_types, rval, subpath)
 
 
 class Cache:
-    '''
-    A base class (and interface description) for caches.
-    Note that Cache objects are not intended to be visible by
-    restricted code.
-    '''
+    """ A base class (and interface description) for caches.
+
+    o Note that Cache objects are not intended to be visible by
+      restricted code.
+    """
 
     def ZCache_invalidate(self, ob):
         raise NotImplementedError
@@ -431,23 +439,15 @@
 
 
 class CacheManager:
-    '''
-    A base class for cache managers.  Implement ZCacheManager_getCache().
-    '''
-
-    ZCacheManager_getCache__roles__ = ()
-    def ZCacheManager_getCache(self):
-        raise NotImplementedError
+    """ A base class for cache managers.
+    
+    o Subclasses must override ZCacheManager_getCache().
+    """
+    security = ClassSecurityInfo()
+    security.setPermissionDefault(ChangeCacheSettings, ('Manager',))
 
     _isCacheManager = 1
 
-    __ac_permissions__ = (
-        ('Change cache settings', ('ZCacheManager_locate',
-                                   'ZCacheManager_setAssociations',
-                                   'ZCacheManager_associate'),
-         ('Manager',)),
-        )
-
     manage_options = (
         {'label':'Associate',
          'action':'ZCacheManager_associate',
@@ -455,6 +455,12 @@
          },
         )
 
+    security.declarePrivate("ZCacheManager_getCache")
+    def ZCacheManager_getCache(self):
+        # Subclasses must override, returning a ZCache implemetnation.
+        raise NotImplementedError
+
+    security.declarePrivate("manage_afterAdd")
     def manage_afterAdd(self, item, container):
         # Adds self to the list of cache managers in the container.
         if aq_base(self) is aq_base(item):
@@ -465,6 +471,7 @@
                 global manager_timestamp
                 manager_timestamp = time.time()
 
+    security.declarePrivate("manage_beforeDelete")
     def manage_beforeDelete(self, item, container):
         # Removes self from the list of cache managers.
         if aq_base(self) is aq_base(item):
@@ -476,12 +483,19 @@
                 global manager_timestamp
                 manager_timestamp = time.time()
 
+    security.declareProtected(ChangeCacheSettings, "ZCacheManager_associate")
     ZCacheManager_associate = DTMLFile('dtml/cmassoc', globals())
 
+    security.declareProtected(ChangeCacheSettings, "ZCacheManager_locate")
     def ZCacheManager_locate(self, require_assoc, subfolders,
                              meta_types=[], REQUEST=None):
-        '''Locates cacheable objects.
-        '''
+        """Locate cacheable objects.
+
+        o If REQUEST is passed, return our 'Associate' tab, populated with
+          the objects found.
+
+        o Otherwise, return the list of objects.
+        """
         ob = aq_parent(aq_inner(self))
         rval = []
         manager_id = self.getId()
@@ -497,10 +511,11 @@
         else:
             return rval
 
+    security.declareProtected(ChangeCacheSettings,
+                              "ZCacheManager_setAssociations")
     def ZCacheManager_setAssociations(self, props=None, REQUEST=None):
-        '''Associates and un-associates cacheable objects with this
-        cache manager.
-        '''
+        """Update associations of cacheable objects with this cache manager.
+        """
         addcount = 0
         remcount = 0
         parent = aq_parent(aq_inner(self))
@@ -533,4 +548,4 @@
                 (addcount, remcount)
                 )
 
-Globals.default__class_init__(CacheManager)
+InitializeClass(CacheManager)




More information about the Zope-Checkins mailing list