[Erp5-report] r38691 jm - in /erp5/trunk/products: CMFActivity/ ERP5/ ERP5/Tool/ ERP5Type/ ...
nobody at svn.erp5.org
nobody at svn.erp5.org
Mon Sep 27 23:16:07 CEST 2010
Author: jm
Date: Mon Sep 27 23:16:06 2010
New Revision: 38691
URL: http://svn.erp5.org?rev=38691&view=rev
Log:
Stop using zope.site.hooks and implement our own getSite using ERP5Site.__of__
zope.site.hooks.setSite is always called too late to be usable and it became
a nightmare to make getSite working early enough.
This fixes portal creation on Zope 2.12, which was broken since r38613.
Removed:
erp5/trunk/products/ERP5Type/patches/getSite.py
Modified:
erp5/trunk/products/CMFActivity/ActivityTool.py
erp5/trunk/products/ERP5/ERP5Site.py
erp5/trunk/products/ERP5/Tool/AlarmTool.py
erp5/trunk/products/ERP5Type/Dynamic/portaltypeclass.py
erp5/trunk/products/ERP5Type/ZopePatch.py
erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py
erp5/trunk/products/ERP5Type/tests/runUnitTest.py
Modified: erp5/trunk/products/CMFActivity/ActivityTool.py
URL: http://svn.erp5.org/erp5/trunk/products/CMFActivity/ActivityTool.py?rev=38691&r1=38690&r2=38691&view=diff
==============================================================================
--- erp5/trunk/products/CMFActivity/ActivityTool.py [utf8] (original)
+++ erp5/trunk/products/CMFActivity/ActivityTool.py [utf8] Mon Sep 27 23:16:06 2010
@@ -67,7 +67,6 @@ except ImportError:
from ZODB.POSException import ConflictError
from Products.MailHost.MailHost import MailHostError
-from zope.site.hooks import setSite
from zLOG import LOG, INFO, WARNING, ERROR
from warnings import warn
@@ -878,9 +877,6 @@ class ActivityTool (Folder, UniqueObject
if not acquired:
return
- portal = self.getPortalObject()
- setSite(portal)
-
# make sure our skin is set-up. On CMF 1.5 it's setup by acquisition,
# but on 2.2 it's by traversal, and our site probably wasn't traversed
# by the timerserver request, which goes into the Zope Control_Panel
Modified: erp5/trunk/products/ERP5/ERP5Site.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/ERP5Site.py?rev=38691&r1=38690&r2=38691&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/ERP5Site.py [utf8] (original)
+++ erp5/trunk/products/ERP5/ERP5Site.py [utf8] Mon Sep 27 23:16:06 2010
@@ -15,6 +15,8 @@
Portal class
"""
+import threading
+from weakref import ref as weakref
from Products.ERP5Type import Globals
from Products.ERP5Type.Globals import package_home
@@ -36,8 +38,7 @@ from Products.ERP5Type.Log import log as
from Products.CMFActivity.Errors import ActivityPendingError
import ERP5Defaults
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
-
-from zope.site.hooks import setSite
+from Products.ERP5Type.Dynamic.portaltypeclass import synchronizeDynamicModules
from zLOG import LOG, INFO
from string import join
@@ -178,6 +179,38 @@ class ReferCheckerBeforeTraverseHook:
'request : "%s"' % http_url)
response.unauthorized()
+
+class _site(threading.local):
+ """Class for getting and setting the site in the thread global namespace
+ """
+ site = ()
+
+ def __new__(cls):
+ self = threading.local.__new__(cls)
+ return self.__get, self.__set
+
+ def __get(self):
+ """Returns the currently processed site
+
+ XXX The returned site is not wrapped in a request.
+ """
+ app, site_id = self.site[-1]
+ app = app()
+ return CMFSite.__of__(app.__dict__[site_id], app)
+
+ def __set(self, site):
+ app = aq_base(site.aq_parent)
+ self.site = [x for x in self.site if x[0]() is not app]
+ # Use weak references for automatic cleanup. In practice, this is probably
+ # useless, because there is no reason a thread reopen the database.
+ self.site.append((weakref(app, self.__del), site.id))
+
+ def __del(self, app):
+ self.site = [x for x in self.site if x[0] is not app]
+
+getSite, setSite = _site()
+
+
class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
"""
The *only* function this class should have is to help in the setup
@@ -213,6 +246,17 @@ class ERP5Site(FolderMixIn, CMFSite, Cac
"""
return self.index_html()
+ def __of__(self, parent):
+ self = CMFSite.__of__(self, parent)
+ # Use a transactional variable for performance reason,
+ # since ERP5Site.__of__ is called quite often.
+ tv = getTransactionalVariable()
+ if 'ERP5Site.__of__' not in tv:
+ tv['ERP5Site.__of__'] = None
+ setSite(self)
+ synchronizeDynamicModules(self)
+ return self
+
def manage_beforeDelete(self, item, container):
# On Zope 2.8, skin is setup during Acquisition (in the .__of__() method).
# On Zope 2.12, skin is setup during __before_publishing_traverse__, which
@@ -359,14 +403,6 @@ class ERP5Site(FolderMixIn, CMFSite, Cac
# and tries to load subobjects of the portal too early
return []
- security.declareProtected(Permissions.AccessContentsInformation, 'objectValues')
- def objectValues(self, *args, **kw):
- # When stepping in an ERP5Site from outside,
- # (e.g. left hand tree frame in {zope root}/manage )
- # we need to set up the site to load portal types inside each site
- setSite(self)
- return super(ERP5Site, self).objectValues(*args, **kw)
-
security.declareProtected(Permissions.AccessContentsInformation, 'searchFolder')
def searchFolder(self, **kw):
"""
@@ -375,7 +411,6 @@ class ERP5Site(FolderMixIn, CMFSite, Cac
"""
if not kw.has_key('parent_uid'):
kw['parent_uid'] = self.uid
- setSite(self)
return self.portal_catalog.searchResults(**kw)
security.declareProtected(Permissions.AccessContentsInformation, 'countFolder')
@@ -386,7 +421,6 @@ class ERP5Site(FolderMixIn, CMFSite, Cac
"""
if not kw.has_key('parent_uid'):
kw['parent_uid'] = self.uid
- setSite(self)
return self.portal_catalog.countResults(**kw)
# Proxy methods for security reasons
@@ -1484,23 +1518,6 @@ class ERP5Generator(PortalGenerator):
# Return the fully wrapped object.
p = parent.this()._getOb(id)
- setSite(p)
-
- try:
- sm = p.getSiteManager()
- except:
- # Zope 2.8, ot site manager, no DefaultTraversable, dont care
- pass
- else:
- import zope
- # XXX hackish, required to setUpERP5Core while in tests,
- # could probably be better
- # (for some reason calling setSite here does not allow
- # the newly created site to find the global DefaultTraversable
- # object)
- sm.registerAdapter(zope.traversing.adapters.DefaultTraversable,
- required=(zope.interface.Interface,))
-
erp5_sql_deferred_connection_string = erp5_sql_connection_string
p._setProperty('erp5_catalog_storage',
erp5_catalog_storage, 'string')
Modified: erp5/trunk/products/ERP5/Tool/AlarmTool.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Tool/AlarmTool.py?rev=38691&r1=38690&r2=38691&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Tool/AlarmTool.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Tool/AlarmTool.py [utf8] Mon Sep 27 23:16:06 2010
@@ -46,7 +46,6 @@ import re
# minimal IP:Port regexp
NODE_RE = re.compile('^\d+\.\d+\.\d+\.\d+:\d+$')
-from zope.site.hooks import setSite
try:
from Products.TimerService import getTimerService
except ImportError:
@@ -211,10 +210,6 @@ class AlarmTool(BaseTool):
if not acquired:
return
try:
-
- portal = self.getPortalObject()
- setSite(portal)
-
# make sure our skin is set-up. On CMF 1.5 it's setup by acquisition,
# but on 2.2 it's by traversal, and our site probably wasn't traversed
# by the timerserver request, which goes into the Zope Control_Panel
Modified: erp5/trunk/products/ERP5Type/Dynamic/portaltypeclass.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Dynamic/portaltypeclass.py?rev=38691&r1=38690&r2=38691&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Dynamic/portaltypeclass.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/Dynamic/portaltypeclass.py [utf8] Mon Sep 27 23:16:06 2010
@@ -6,7 +6,6 @@ import sys
import inspect
from types import ModuleType
-from zope.site.hooks import getSite
from Products.ERP5Type.Globals import InitializeClass
from Products.ERP5Type.Utils import setDefaultClassProperties
@@ -54,6 +53,7 @@ def portal_type_factory(portal_type_name
# before creating any Base Type object
type_class = "BusinessTemplate"
else:
+ from Products.ERP5.ERP5Site import getSite
site = getSite()
type_tool = site.portal_types
Modified: erp5/trunk/products/ERP5Type/ZopePatch.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/ZopePatch.py?rev=38691&r1=38690&r2=38691&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/ZopePatch.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/ZopePatch.py [utf8] Mon Sep 27 23:16:06 2010
@@ -70,4 +70,3 @@ from Products.ERP5Type.patches import Zo
from Products.ERP5Type.patches.PropertyManager import ERP5PropertyManager
from Products.ERP5Type.patches.DCWorkflow import ValidationFailed, ERP5TransitionDefinition
from Products.ERP5Type.patches.BTreeFolder2 import ERP5BTreeFolder2Base
-from Products.ERP5Type.patches.getSite import getSite
Removed: erp5/trunk/products/ERP5Type/patches/getSite.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/patches/getSite.py?rev=38690&view=auto
==============================================================================
--- erp5/trunk/products/ERP5Type/patches/getSite.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/patches/getSite.py (removed)
@@ -1,42 +0,0 @@
-from Products.ERP5Type import Globals
-module_name = 'zope.site.hooks'
-try:
- hooks = __import__(module_name, {}, {}, module_name)
- _getSite = hooks.getSite
- _setSite = hooks.setSite
-except ImportError:
- # backwards compatibility for Zope < 2.12
- import imp, sys
- import zope
- try:
- site = zope.site
- except:
- sys.modules['zope.site'] = zope.site = imp.new_module('zope.site')
- sys.modules[module_name] = hooks = imp.new_module(module_name)
-
- def _getSite():
- return None
- def _setSite(site=None):
- request = Globals.get_request()
- if not (None in (site, request) or site in request.get('PARENTS', ())):
- request['PARENTS'] = [site]
-
-# patch getSite so that it works everywhere
-def getSite():
- site = _getSite()
- if site is None:
- parents = Globals.get_request()['PARENTS']
- for site in parents[::-1]:
- if getattr(site, 'getPortalObject', None) is not None:
- break
- else:
- raise AttributeError("getSite() can't retrieve the site")
- return site
-hooks.getSite = getSite
-
-def setSite(site=None):
- _setSite(site)
- if site is not None:
- from Products.ERP5Type.Dynamic.portaltypeclass import synchronizeDynamicModules
- synchronizeDynamicModules(site)
-hooks.setSite = setSite
Modified: erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py?rev=38691&r1=38690&r2=38691&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py [utf8] Mon Sep 27 23:16:06 2010
@@ -50,6 +50,14 @@ Products.ERP5Type.Utils.get_request = ge
Globals.get_request = get_request
try:
+ from zope.site.hooks import setSite
+except ImportError:
+ # BACK: Zope 2.8. setSite is somewhere else, and we can't use it anyway
+ # since ERP5Site is not yet an ISite. Remove once we drop support for 2.8
+ def setSite(site=None):
+ pass
+
+try:
import itools.zope
itools.zope.get_context = get_context
except ImportError:
@@ -221,8 +229,6 @@ failed_portal_installation = {}
# this is a mapping 'list of business template -> boolean
setup_done = {}
-from zope.site.hooks import setSite
-
def _getConnectionStringDict():
"""Returns the connection strings used for this test.
"""
Modified: erp5/trunk/products/ERP5Type/tests/runUnitTest.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/tests/runUnitTest.py?rev=38691&r1=38690&r2=38691&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/tests/runUnitTest.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/tests/runUnitTest.py [utf8] Mon Sep 27 23:16:06 2010
@@ -536,6 +536,7 @@ def runUnitTestList(test_list, verbosity
import transaction
transaction.commit()
ZopeTestCase.close(app)
+ del app
if zeo_client_pid_list is None:
result = suite()
More information about the Erp5-report
mailing list