Commit dbb476e6 authored by Hanno Schlichting's avatar Hanno Schlichting

Remove ZCacheable logic and StandardCacheManagers dependency.

parent dabb9766
......@@ -30,6 +30,8 @@ Features Added
Restructuring
+++++++++++++
- Remove ZCacheable logic and StandardCacheManagers dependency.
- Stop mixing in `Five.bbb.AcquisitionBBB` into browser components.
- Integrate `five.pt` code directly into `Products.PageTemplates`.
......@@ -309,5 +311,4 @@ Restructuring
``Products.SiteErrorLog``
``Products.StandardCacheManagers``
``Products.ZCatalog``
``Products.ZCTextIndex``
``Record``
......@@ -72,7 +72,6 @@ eggs =
Products.PythonScripts
Products.Sessions
Products.SiteErrorLog
Products.StandardCacheManagers
Products.TemporaryFolder
Products.ZCatalog
Record
......
......@@ -25,7 +25,6 @@ Products.MailHost = git ${remotes:github}/Products.MailHost pushurl=${remotes:gi
Products.PythonScripts = git ${remotes:github}/Products.PythonScripts pushurl=${remotes:github_push}/Products.PythonScripts
Products.Sessions = git ${remotes:github}/Products.Sessions.git pushurl=${remotes:github_push}/Products.Sessions
Products.SiteErrorLog = git ${remotes:github}/Products.SiteErrorLog pushurl=${remotes:github_push}/Products.SiteErrorLog
Products.StandardCacheManagers = git ${remotes:github}/Products.StandardCacheManagers pushurl=${remotes:github_push}/Products.StandardCacheManagers
Products.TemporaryFolder = git ${remotes:github}/Products.TemporaryFolder pushurl=${remotes:github_push}/Products.TemporaryFolder branch=master
Products.ZCatalog = git ${remotes:github}/Products.ZCatalog pushurl=${remotes:github_push}/Products.ZCatalog branch=master
Products.ZCTextIndex = git ${remotes:github}/Products.ZCTextIndex pushurl=${remotes:github_push}/Products.ZCTextIndex
......
This diff is collapsed.
......@@ -59,7 +59,6 @@ class DTMLDocument(PropertyManager, DTMLMethod):
file = file.read()
self.munge(file)
self.ZCacheable_invalidate()
if REQUEST:
message = "Content uploaded."
return self.manage_main(self, REQUEST, manage_tabs_message=message)
......@@ -69,12 +68,6 @@ class DTMLDocument(PropertyManager, DTMLMethod):
o If supplied, use REQUEST mapping, Response, and key word arguments.
"""
if not self._cache_namespace_keys:
data = self.ZCacheable_get(default=_marker)
if data is not _marker:
# Return cached results.
return data
__traceback_supplement__ = (PathTracebackSupplement, self)
kw['document_id'] = self.getId()
kw['document_title'] = self.title
......@@ -94,15 +87,11 @@ class DTMLDocument(PropertyManager, DTMLMethod):
result = r
else:
result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result
r = HTML.__call__(self, (client, bself), REQUEST, **kw)
if RESPONSE is None or not isinstance(r, str):
if not self._cache_namespace_keys:
self.ZCacheable_set(r)
return r
finally:
......@@ -116,8 +105,6 @@ class DTMLDocument(PropertyManager, DTMLMethod):
c, e = guess_content_type(self.__name__, r)
RESPONSE.setHeader('Content-Type', c)
result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result
......
......@@ -36,7 +36,6 @@ from OFS.role import RoleManager
from OFS.SimpleItem import Item_w__name__
from zExceptions import Forbidden, ResourceLockedError
from zExceptions.TracebackSupplement import PathTracebackSupplement
from ZPublisher.Iterators import IStreamIterator
from zope.contenttype import guess_content_type
if sys.version_info >= (3, ):
......@@ -49,14 +48,13 @@ class DTMLMethod(RestrictedDTML,
HTML,
Implicit,
RoleManager,
Item_w__name__,
Cacheable):
Cacheable,
Item_w__name__):
""" DocumentTemplate.HTML objects that act as methods of their containers.
"""
meta_type = 'DTML Method'
_proxy_roles = ()
index_html = None # Prevent accidental acquisition
_cache_namespace_keys = ()
security = ClassSecurityInfo()
security.declareObjectProtected(View)
......@@ -74,8 +72,7 @@ class DTMLMethod(RestrictedDTML,
{'label': 'Proxy', 'action': 'manage_proxyForm'},
) +
RoleManager.manage_options +
Item_w__name__.manage_options +
Cacheable.manage_options
Item_w__name__.manage_options
)
# More reasonable default for content-type for http HEAD requests.
......@@ -91,27 +88,6 @@ class DTMLMethod(RestrictedDTML,
o If supplied, use the REQUEST mapping, Response, and key word
arguments.
"""
if not self._cache_namespace_keys:
data = self.ZCacheable_get(default=_marker)
if data is not _marker:
if (IStreamIterator.isImplementedBy(data) and
RESPONSE is not None):
# This is a stream iterator and we need to set some
# headers now before giving it to medusa
headers_get = RESPONSE.headers.get
if headers_get('content-length', None) is None:
RESPONSE.setHeader('content-length', len(data))
if (headers_get('content-type', None) is None and
headers_get('Content-type', None) is None):
ct = (self.__dict__.get('content_type') or
self.default_content_type)
RESPONSE.setHeader('content-type', ct)
# Return cached results.
return data
__traceback_supplement__ = (PathTracebackSupplement, self)
kw['document_id'] = self.getId()
kw['document_title'] = self.title
......@@ -132,14 +108,10 @@ class DTMLMethod(RestrictedDTML,
result = r
else:
result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result
r = HTML.__call__(self, client, REQUEST, **kw)
if RESPONSE is None or not isinstance(r, str):
if not self._cache_namespace_keys:
self.ZCacheable_set(r)
return r
finally:
......@@ -155,59 +127,24 @@ class DTMLMethod(RestrictedDTML,
c, e = guess_content_type(self.getId(), r)
RESPONSE.setHeader('Content-Type', c)
result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result
def validate(self, inst, parent, name, value, md=None):
return getSecurityManager().validate(inst, parent, name, value)
def ZDocumentTemplate_beforeRender(self, md, default):
# Tries to get a cached value.
if self._cache_namespace_keys:
# Use the specified keys from the namespace to identify a
# cache entry.
kw = {}
for key in self._cache_namespace_keys:
try:
val = md[key]
except:
val = None
kw[key] = val
return self.ZCacheable_get(keywords=kw, default=default)
return default
def ZDocumentTemplate_afterRender(self, md, result):
# Tries to set a cache value.
if self._cache_namespace_keys:
kw = {}
for key in self._cache_namespace_keys:
try:
val = md[key]
except:
val = None
kw[key] = val
self.ZCacheable_set(result, keywords=kw)
security.declareProtected(change_dtml_methods, 'ZCacheable_configHTML')
ZCacheable_configHTML = DTMLFile('dtml/cacheNamespaceKeys', globals())
pass
security.declareProtected(change_dtml_methods, 'getCacheNamespaceKeys')
def getCacheNamespaceKeys(self):
# Return the cacheNamespaceKeys.
return self._cache_namespace_keys
return ()
security.declareProtected(change_dtml_methods, 'setCacheNamespaceKeys')
def setCacheNamespaceKeys(self, keys, REQUEST=None):
# Set the list of names looked up to provide a cache key.
ks = []
for key in keys:
key = str(key).strip()
if key:
ks.append(key)
self._cache_namespace_keys = tuple(ks)
if REQUEST is not None:
return self.ZCacheable_manage(self, REQUEST)
pass
security.declareProtected(View, 'get_size')
def get_size(self):
......@@ -245,7 +182,6 @@ class DTMLMethod(RestrictedDTML,
if not isinstance(data, basestring):
data = data.read()
self.munge(data)
self.ZCacheable_invalidate()
if REQUEST:
message = "Saved changes."
return self.manage_main(self, REQUEST, manage_tabs_message=message)
......@@ -264,7 +200,6 @@ class DTMLMethod(RestrictedDTML,
file = file.read()
self.munge(file)
self.ZCacheable_invalidate()
if REQUEST:
message = "Saved changes."
return self.manage_main(self, REQUEST, manage_tabs_message=message)
......@@ -299,7 +234,6 @@ class DTMLMethod(RestrictedDTML,
self._validateProxy(REQUEST, roles)
self._validateProxy(REQUEST)
self._proxy_roles = tuple(roles)
self.ZCacheable_invalidate()
if REQUEST:
message = "Saved changes."
return self.manage_proxyForm(self, REQUEST,
......@@ -327,7 +261,6 @@ class DTMLMethod(RestrictedDTML,
body = REQUEST.get('BODY', '')
self._validateProxy(REQUEST)
self.munge(body)
self.ZCacheable_invalidate()
RESPONSE.setStatus(204)
return RESPONSE
......
......@@ -97,7 +97,6 @@ class File(Persistent, Implicit, PropertyManager,
implementedBy(PropertyManager),
implementedBy(RoleManager),
implementedBy(Item_w__name__),
implementedBy(Cacheable),
IWriteLock,
HTTPRangeSupport.HTTPRangeInterface)
......@@ -121,8 +120,7 @@ class File(Persistent, Implicit, PropertyManager,
manage_options = (
({'label': 'Edit', 'action': 'manage_main'}, ) +
RoleManager.manage_options +
Item_w__name__.manage_options +
Cacheable.manage_options
Item_w__name__.manage_options
)
_properties = (
......@@ -382,13 +380,6 @@ class File(Persistent, Implicit, PropertyManager,
"""
if self._if_modified_since_request_handler(REQUEST, RESPONSE):
# we were able to handle this by returning a 304
# unfortunately, because the HTTP cache manager uses the cache
# API, and because 304 responses are required to carry the Expires
# header for HTTP/1.1, we need to call ZCacheable_set here.
# This is nonsensical for caches other than the HTTP cache manager
# unfortunately.
self.ZCacheable_set(None)
return ''
if self.precondition and hasattr(self, str(self.precondition)):
......@@ -410,17 +401,6 @@ class File(Persistent, Implicit, PropertyManager,
RESPONSE.setHeader('Content-Length', self.size)
RESPONSE.setHeader('Accept-Ranges', 'bytes')
if self.ZCacheable_isCachingEnabled():
result = self.ZCacheable_get(default=None)
if result is not None:
# We will always get None from RAMCacheManager and HTTP
# Accelerated Cache Manager but we will get
# something implementing the IStreamIterator interface
# from a "FileCacheManager"
return result
self.ZCacheable_set(None)
data = self.data
if isinstance(data, str):
RESPONSE.setBase(None)
......@@ -458,8 +438,6 @@ class File(Persistent, Implicit, PropertyManager,
size = len(data)
self.size = size
self.data = data
self.ZCacheable_invalidate()
self.ZCacheable_set(None)
self.http__refreshEtag()
security.declareProtected(change_images_and_files, 'manage_edit')
......@@ -479,8 +457,6 @@ class File(Persistent, Implicit, PropertyManager,
del self.precondition
if filedata is not None:
self.update_data(filedata, content_type, len(filedata))
else:
self.ZCacheable_invalidate()
notify(ObjectModifiedEvent(self))
......@@ -641,18 +617,6 @@ class File(Persistent, Implicit, PropertyManager,
def manage_FTPget(self):
"""Return body for ftp."""
RESPONSE = self.REQUEST.RESPONSE
if self.ZCacheable_isCachingEnabled():
result = self.ZCacheable_get(default=None)
if result is not None:
# We will always get None from RAMCacheManager but we will
# get something implementing the IStreamIterator interface
# from FileCacheManager.
# the content-length is required here by HTTPResponse,
# even though FTP doesn't use it.
RESPONSE.setHeader('Content-Length', self.size)
return result
data = self.data
if isinstance(data, str):
RESPONSE.setBase(None)
......@@ -809,8 +773,7 @@ class Image(File):
manage_options = (
({'label': 'Edit', 'action': 'manage_main'}, ) +
RoleManager.manage_options +
Item_w__name__.manage_options +
Cacheable.manage_options
Item_w__name__.manage_options
)
manage_editForm = DTMLFile('dtml/imageEdit', globals(),
......@@ -848,8 +811,6 @@ class Image(File):
if content_type is not None:
self.content_type = content_type
self.ZCacheable_invalidate()
self.ZCacheable_set(None)
self.http__refreshEtag()
def __str__(self):
......
......@@ -4,7 +4,4 @@
<five:deprecatedManageAddDelete
class="OFS.userfolder.BasicUserFolder"/>
<five:deprecatedManageAddDelete
class="OFS.Cache.CacheManager"/>
</configure>
<p class="form-text">
Names from the DTML namespace to use as cache keys:
</p>
<textarea name="keys:lines" cols="40" rows="5"><dtml-in
getCacheNamespaceKeys>&dtml-sequence-item;
</dtml-in></textarea>
<br>
<div class="form-element">
<input class="form-element" type="submit"
name="setCacheNamespaceKeys:method" value="Save Changes">
</div>
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<form action="&dtml-absolute_url;" method="POST">
<div class="form-element">
<span class="form-label">
Cache this object using:
</span>
<select name="manager_id">
<option value="">(None)</option>
<dtml-in ZCacheable_getManagerIds mapping>
<option value="&dtml-id;" <dtml-if
expr="id == ZCacheable_getManagerId()"
>selected="selected"</dtml-if>>&dtml-id;
<dtml-if title>(&dtml-title;)</dtml-if></option>
</dtml-in>
</select>
<br />
<input class="form-element" type="submit"
name="ZCacheable_setManagerId:method" value="Save Changes">
</div>
<dtml-if ZCacheable_getManagerURL>
<p class="form-text">
<a href="&dtml-ZCacheable_getManagerURL;/manage_main">Cache Settings</a>
</p>
<div class="form-element">
<input class="form-element" type="submit"
name="ZCacheable_invalidate:method" value="Invalidate">
</div>
</dtml-if>
<dtml-var ZCacheable_configHTML>
</form>
<dtml-var manage_page_footer>
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<form action="&dtml-URL1;" name="objectItems" method="POST">
<dtml-if show_results>
<dtml-if results>
<p class="form-help">
Select which objects should be cached using this cache manager. Only
those objects for which you have the "Change cache settings" permission
are shown.
</p>
<table width="100%" cellspacing="0" cellpadding="2" border="0">
<dtml-in results mapping sort=sortkey>
<dtml-if sequence-odd>
<tr class="row-normal">
<dtml-else>
<tr class="row-hilite">
</dtml-if>
<td align="left" valign="top">
<input type="checkbox" name="associate_&dtml-path;:int" value="1"<dtml-if
associated> checked="checked"</dtml-if>>
<input type="hidden" name="associate_&dtml-path;:int:default" value="0">
</td>
<td align="left" valign="top">
<div class="form-text">
<a href="../&dtml-path;/manage_main">&dtml-path;</a><dtml-if
title>(&dtml-title;)</dtml-if>
</div>
</td>
</tr>
</dtml-in>
<tr>
<td></td>
<td align="left" valign="top">
<div class="form-element">
<input type="submit" name="ZCacheManager_setAssociations:method"
value="Save Changes">
</div>
</td>
</tr>
</table>
</form>
<dtml-else>
<p class="form-text">
No objects matched your query.
</p>
</dtml-if>
<hr>
</dtml-if>
<form target="&dtml-URL1;" method="post">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Locate cacheable objects:
</div>
</td>
<td align="left" valign="top">
<div class="form-text">
<input type="radio" name="require_assoc:int" value="0"
checked="checked"> All
<input type="radio" name="require_assoc:int" value="1">
Associated with this cache manager
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Of the type(s):
</div>
</td>
<td align="left" valign="top">
<div class="form-element">
<select multiple="multiple" name="meta_types:list" size="5">
<option value="" selected>All</option>
<dtml-in all_meta_types mapping sort=name>
<option value="&dtml-name;">&dtml-name;</option>
</dtml-in>
</select>
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
</td>
<td align="left" valign="top">
<div class="form-text">
<input type="checkbox" name="subfolders:int" value="1" checked="checked">
<input type="hidden" name="subfolders:int" value="0">
Search subfolders
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
</td>
<td align="left" valign="top">
<div class="form-element">
<br>
<input type="submit" name="ZCacheManager_locate:method" value="Locate">
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>
import unittest
from OFS.Cache import CacheManager
from OFS.Folder import Folder
from OFS.SimpleItem import SimpleItem
from OFS.metaconfigure import setDeprecatedManageAddDelete
class DummyCacheManager(CacheManager, SimpleItem):
def __init__(self, id, *args, **kw):
self.id = id
setDeprecatedManageAddDelete(DummyCacheManager)
class CacheTests(unittest.TestCase):
def test_managersExist(self):
from OFS.Cache import managersExist
from OFS.DTMLMethod import DTMLMethod
root = Folder('root')
root._setObject('root_cache', DummyCacheManager('root_cache'))
root._setObject('child', Folder('child'))
root.child._setObject('child_cache', DummyCacheManager('child_cache'))
root.child._setObject('child_content', DTMLMethod('child_content'))
# To begin with, cache managers will be found correctly
# using managersExist
self.assertTrue(managersExist(root.child.child_content))
# Now we delete the cache in the child folder
root.child.manage_delObjects(['child_cache'])
# The parent_cache should still trigger managersExist
self.assertTrue(managersExist(root.child.child_content))
......@@ -11,8 +11,6 @@ from cStringIO import StringIO
from Acquisition import aq_base
from OFS.Application import Application
from OFS.SimpleItem import SimpleItem
from OFS.Cache import ZCM_MANAGERS
from OFS.Image import Pdata
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
......@@ -57,41 +55,6 @@ def aputrequest(file, content_type):
return req
class DummyCache:
def __init__(self):
self.clear()
def ZCache_set(self, ob, data, view_name='', keywords=None,
mtime_func=None):
self.set = (ob, data)
def ZCache_get(self, ob, data, view_name='', keywords=None,
mtime_func=None):
self.get = ob
if self.si:
return self.si
def ZCache_invalidate(self, ob):
self.invalidated = ob
def clear(self):
self.set = None
self.get = None
self.invalidated = None
self.si = None
def setStreamIterator(self, si):
self.si = si
ADummyCache = DummyCache()
class DummyCacheManager(SimpleItem):
def ZCacheManager_getCache(self):
return ADummyCache
class EventCatcher(object):
def __init__(self):
......@@ -139,13 +102,9 @@ class FileTests(unittest.TestCase):
self.root = a
responseOut = self.responseOut = StringIO()
self.app = makerequest(self.root, stdout=responseOut)
self.app.dcm = DummyCacheManager()
factory = getattr(self.app, self.factory)
factory('file',
file=self.data, content_type=self.content_type)
self.app.file.ZCacheable_setManagerId('dcm')
self.app.file.ZCacheable_setEnabled(enabled=1)
setattr(self.app, ZCM_MANAGERS, ('dcm',))
# Hack, we need a _p_mtime for the file, so we make sure that it
# has one.
transaction.commit()
......@@ -174,7 +133,6 @@ class FileTests(unittest.TestCase):
del self.responseOut
del self.root
del self.connection
ADummyCache.clear()
self.eventCatcher.tearDown()
def testViewImageOrFile(self):
......@@ -184,8 +142,6 @@ class FileTests(unittest.TestCase):
self.file.update_data('foo')
self.assertEqual(self.file.size, 3)
self.assertEqual(self.file.data, 'foo')
self.assertTrue(ADummyCache.invalidated)
self.assertTrue(ADummyCache.set)
def testReadData(self):
s = "a" * (2 << 16)
......@@ -210,8 +166,6 @@ class FileTests(unittest.TestCase):
self.file.manage_edit('foobar', 'text/plain', filedata='ASD')
self.assertEqual(self.file.title, 'foobar')
self.assertEqual(self.file.content_type, 'text/plain')
self.assertTrue(ADummyCache.invalidated)
self.assertTrue(ADummyCache.set)
self.assertEquals(1, len(self.eventCatcher.modified))
self.assertTrue(self.eventCatcher.modified[0].object is self.file)
......@@ -219,7 +173,6 @@ class FileTests(unittest.TestCase):
self.file.manage_edit('foobar', 'text/plain')
self.assertEqual(self.file.title, 'foobar')
self.assertEqual(self.file.content_type, 'text/plain')
self.assertTrue(ADummyCache.invalidated)
self.assertEquals(1, len(self.eventCatcher.modified))
self.assertTrue(self.eventCatcher.modified[0].object is self.file)
......@@ -308,8 +261,6 @@ class ImageTests(FileTests):
self.assertEqual(self.file.data, self.data)
self.assertEqual(self.file.width, 16)
self.assertEqual(self.file.height, 16)
self.assertTrue(ADummyCache.invalidated)
self.assertTrue(ADummyCache.set)
def testStr(self):
self.assertEqual(
......
......@@ -88,7 +88,7 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
manage_options = (
{'label': 'Edit', 'action': 'pt_editForm'},
) + SimpleItem.manage_options + Cacheable.manage_options
) + SimpleItem.manage_options
_properties = (
{'id': 'title', 'type': 'ustring', 'mode': 'w'},
......@@ -164,7 +164,6 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
if not is_unicode:
text = unicode(text, encoding)
self.ZCacheable_invalidate()
super(ZopePageTemplate, self).pt_edit(text, content_type)
pt_editForm = PageTemplateFile('www/ptEdit', globals(),
......@@ -204,11 +203,6 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
title = unicode(title, encoding)
self._setPropValue('title', title)
def _setPropValue(self, id, value):
""" set a property and invalidate the cache """
PropertyManager._setPropValue(self, id, value)
self.ZCacheable_invalidate()
security.declareProtected(change_page_templates, 'pt_upload')
def pt_upload(self, REQUEST, file='', encoding='utf-8'):
"""Replace the document with the text in file."""
......@@ -248,14 +242,12 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
return c
def write(self, text):
if not isinstance(text, unicode):
text, encoding = convertToUnicode(text,
self.content_type,
preferred_encodings)
self.output_encoding = encoding
self.ZCacheable_invalidate()
ZopePageTemplate.inheritedAttribute('write')(self, text)
def _exec(self, bound_names, args, kw):
......@@ -273,25 +265,11 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
security = getSecurityManager()
bound_names['user'] = security.getUser()
# Retrieve the value from the cache.
keyset = None
if self.ZCacheable_isCachingEnabled():
# Prepare a cache key.
keyset = {'here': self._getContext(),
'bound_names': bound_names}
result = self.ZCacheable_get(keywords=keyset)
if result is not None:
# Got a cached value.
return result
# Execute the template in a new security context.
security.addContext(self)
try:
result = self.pt_render(extra_context=bound_names)
if keyset is not None:
# Store the result in the cache.
self.ZCacheable_set(result, keywords=keyset)
return result
finally:
security.removeContext(self)
......
......@@ -24,7 +24,6 @@ Products.MailHost = 3.0
Products.PythonScripts = 4.0
Products.Sessions = 4.0
Products.SiteErrorLog = 4.0
Products.StandardCacheManagers = 3.0
Products.TemporaryFolder = 4.0
Products.ZCatalog = 4.0a2
Products.ZCTextIndex = 4.0
......
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