[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