Commit 1d344ac3 authored by Hanno Schlichting's avatar Hanno Schlichting

Moved the code handling ZCML loading into the ``Zope2.App`` package. The...

Moved the code handling ZCML loading into the ``Zope2.App`` package. The component architecture is now setup before the application object is created or any database connections are opened. So far the CA was setup somewhat randomly in the startup process, when the ``Five`` product was initialized.
parent 4c2c8008
......@@ -11,6 +11,11 @@ Trunk (unreleased)
Restructuring
+++++++++++++
- Moved the code handling ZCML loading into the ``Zope2.App`` package. The
component architecture is now setup before the application object is created
or any database connections are opened. So far the CA was setup somewhat
randomly in the startup process, when the ``Five`` product was initialized.
- Downgrade the ``manage_* is discouraged. You should use event subscribers
instead`` warnings to debug level logging. This particular warning hasn't
motivated anyone to actually change any code.
......
......@@ -13,12 +13,13 @@ from AccessControl.SecurityManagement import noSecurityManager
from OFS.SimpleItem import SimpleItem
from OFS.Folder import Folder
from Zope2.App import zcml
from zope import interface
from zope import component
from zope.component.interfaces import IObjectEvent
from zope.testing import cleanup
from Products.Five import zcml
class EventLogger(object):
......@@ -59,15 +60,13 @@ class EventLayer:
@classmethod
def setUp(cls):
cleanup.cleanUp()
zcml._initialized = 0
zcml.load_site()
zcml.load_site(force=True)
component.provideHandler(eventlog.trace, (ITestItem, IObjectEvent))
component.provideHandler(eventlog.trace, (ITestFolder, IObjectEvent))
@classmethod
def tearDown(cls):
cleanup.cleanUp()
zcml._initialized = 0
class EventTest(unittest.TestCase):
......
......@@ -6,7 +6,6 @@ Zope2.startup()
import transaction
from zope.testing import cleanup
from Products.Five import zcml
from Testing.makerequest import makerequest
......@@ -16,6 +15,8 @@ from AccessControl.SecurityManagement import noSecurityManager
from OFS.SimpleItem import SimpleItem
from OFS.Folder import Folder
from Zope2.App import zcml
class EventLogger(object):
def __init__(self):
......@@ -64,15 +65,13 @@ class HookLayer:
@classmethod
def setUp(cls):
cleanup.cleanUp()
zcml._initialized = 0
zcml.load_site()
zcml.load_site(force=True)
setDeprecatedManageAddDelete(TestItem)
setDeprecatedManageAddDelete(TestFolder)
@classmethod
def tearDown(cls):
cleanup.cleanUp()
zcml._initialized = 0
class HookTest(unittest.TestCase):
......
......@@ -15,7 +15,7 @@ from OFS.metaconfigure import setDeprecatedManageAddDelete
from OFS.ObjectManager import ObjectManager
from OFS.SimpleItem import SimpleItem
import Products.Five
from Products.Five import zcml
from Zope2.App import zcml
from zExceptions import BadRequest
logger = getLogger('OFS.subscribers')
......
......@@ -414,7 +414,7 @@ def test_traversable():
publishing they do unrestrictedTraverse.
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> from Testing.makerequest import makerequest
>>> self.app = makerequest(self.app)
......@@ -594,7 +594,7 @@ def test_view_doesnt_shadow_attribute():
... />
... </configure>'''
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_string(configure_zcml)
......
......@@ -24,7 +24,7 @@ def test_registerClass():
>>> setUp()
>>> import Products
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> from Products.Five.tests.testing.simplecontent import SimpleContent
>>> from Products.Five.tests.testing.simplecontent import ISimpleContent
>>> from persistent.interfaces import IPersistent
......
......@@ -30,7 +30,7 @@ def test_registerPackage():
>>> setUp()
>>> import Products
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config('meta.zcml', Products.Five)
Make sure a python package with a valid initialize gets its
......
......@@ -15,22 +15,12 @@
$Id$
"""
from Products.Five import zcml
# public API provided by Five
# usage: from Products.Five import <something>
from Products.Five.browser import BrowserView
from Products.Five.skin.standardmacros import StandardMacros
# load the site's ZCML tree (usually site.zcml) upon product
# initialization
def initialize(context):
from zope.schema.vocabulary import setVocabularyRegistry
from Products.Five.schema import Zope2VocabularyRegistry
zcml.load_site()
setVocabularyRegistry(Zope2VocabularyRegistry())
# some convenience methods/decorators
def fivemethod(func):
......
......@@ -5,7 +5,7 @@ This test tests publishing aspects of browser pages. Let's register
some:
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config('aqlegacy.zcml', package=Products.Five.browser.tests)
......
......@@ -4,7 +4,7 @@ Test browser pages
Let's register a quite large amount of test pages:
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config('pages.zcml', package=Products.Five.browser.tests)
......
......@@ -5,7 +5,7 @@ This test tests publishing aspects of browser pages. Let's register
some:
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config('pages.zcml', package=Products.Five.browser.tests)
......
......@@ -9,7 +9,7 @@ new tal expression in providers.zcml:
>>> from zope.contentprovider import interfaces
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config('provider.zcml', package=Products.Five.browser.tests)
......
......@@ -4,7 +4,7 @@ Testing resources
Set up the test fixtures:
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config('resource.zcml', package=Products.Five.browser.tests)
......
......@@ -4,7 +4,7 @@ Functional Resource Test
Set up the test fixtures:
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config('resource.zcml', package=Products.Five.browser.tests)
......
......@@ -4,7 +4,7 @@ Test layer and skin support
Let's register a test layer and test skin:
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config("skin.zcml", package=Products.Five.browser.tests)
......
......@@ -23,7 +23,7 @@ def test_absoluteurl():
First we make some preparations:
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
......
......@@ -24,7 +24,7 @@ def test_default_view():
default viewable:
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config('defaultview.zcml', Products.Five.browser.tests)
......@@ -114,7 +114,7 @@ def test_default_method_args_marshalling():
>>> import AccessControl
>>> import Products.Five.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config('meta.zcml', Products.Five)
>>> zcml.load_config("permissions.zcml", AccessControl)
>>> zcml.load_config('directives.zcml', Products.Five.tests)
......
......@@ -40,7 +40,7 @@ def test_zpt_i18n():
... </configure>'''
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_string(configure_zcml)
......
......@@ -25,7 +25,7 @@ def test_menu():
>>> import AccessControl
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("meta.zcml", Products.Five)
>>> zcml.load_config("permissions.zcml", AccessControl)
>>> zcml.load_config('menu.zcml', package=Products.Five.browser.tests)
......
......@@ -23,7 +23,7 @@ def test_view_with_unwrapped_context():
provide dummy contexts which are not wrapped.
>>> import Products.Five.browser.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config('pages.zcml', package=Products.Five.browser.tests)
>>> from Products.Five.tests.testing import simplecontent as sc
......
......@@ -25,7 +25,7 @@ def test_traversable():
Test the behaviour of Five-traversable classes.
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
``SimpleContent`` is a traversable class by default. Its fallback
......@@ -211,7 +211,7 @@ def test_view_doesnt_shadow_attribute():
... />
... </configure>'''
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_string(configure_zcml)
......
......@@ -23,7 +23,7 @@ def test_check_permission():
... </configure>'''
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_string(configure_zcml)
......
......@@ -13,7 +13,7 @@ be pickled properly:
Load all of Five's configuration (this is a functional test):
>>> import Products.Five
>>> from Products.Five.zcml import load_config
>>> from Zope2.App.zcml import load_config
>>> load_config('configure.zcml', package=Products.Five)
Enable local component lookup hooks:
......
##############################################################################
#
# Copyright (c) 2004, 2005 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Five-specific schema support
# BBB
$Id$
"""
from zope.component import getUtility
from zope.interface import implements
from zope.schema.interfaces import IVocabularyRegistry
from zope.schema.interfaces import IVocabularyFactory
class Zope2VocabularyRegistry(object):
"""IVocabularyRegistry that supports global and local utilities.
Cloned from the version in zope.app.schema.vocabulary: it was the
only feature in that package!
"""
implements(IVocabularyRegistry)
__slots__ = ()
def get(self, context, name):
"""See zope.schema.interfaces.IVocabularyRegistry.
"""
factory = getUtility(IVocabularyFactory, name)
return factory(context)
from Zope2.App.schema import Zope2VocabularyRegistry
......@@ -27,7 +27,7 @@ def test_standard_macros():
>>> manage_addFiveTraversableFolder(self.folder, 'testoid', 'Testoid')
>>> import Products.Five.skin.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config('configure.zcml', package=Products.Five)
>>> zcml.load_config('configure.zcml', package=Products.Five.skin.tests)
......
......@@ -22,7 +22,7 @@ def test_boilerplate():
>>> setUp()
>>> import Products.Five.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config('boilerplate.zcml', Products.Five.tests)
>>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
......
......@@ -28,7 +28,7 @@ def test_directives():
But first, we load the configuration file:
>>> import Products.Five.tests
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config('meta.zcml', Products.Five)
>>> zcml.load_config('directives.zcml', Products.Five.tests)
......
......@@ -24,7 +24,7 @@ def test_directive():
directive:
>>> import zope.i18n
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config('meta.zcml', zope.i18n)
Let's register the gettext locales using the ZCML directive:
......
......@@ -72,7 +72,7 @@ def test_size():
... </configure>'''
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config('meta.zcml', Products.Five)
>>> zcml.load_string(configure_zcml)
......
......@@ -25,7 +25,7 @@ def test_editview():
>>> import AccessControl
>>> import Products.Five
>>> import Products.Five.utilities
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config('meta.zcml', Products.Five)
>>> zcml.load_config('permissions.zcml', AccessControl)
>>> zcml.load_config('configure.zcml', Products.Five.utilities)
......
......@@ -12,7 +12,7 @@ register content for those regions.
Setup traversal stuff
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
Set a loose security policy because these are unit tests, security will be
......
......@@ -5,7 +5,7 @@ The ``viewletManager`` Directive
Setup traversal stuff
>>> import Products.Five
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
>>> zcml.load_config("configure.zcml", Products.Five)
The ``viewletManager`` directive allows you to quickly register a new viewlet
......@@ -13,7 +13,6 @@ manager without worrying about the details of the ``adapter``
directive. Before we can use the directives, we have to register their
handlers by executing the package's meta configuration:
>>> from Products.Five import zcml
>>> context = zcml.load_string('''
... <configure i18n_domain="zope">
... <include package="Products.Five.viewlet" file="meta.zcml" />
......
##############################################################################
#
# Copyright (c) 2004, 2005 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ZCML machinery
# BBB
$Id$
"""
import os
import os.path
from zope.configuration import xmlconfig
from Zope2.App.zcml import _context
from Zope2.App.zcml import _initialized
_initialized = False
_context = None
def load_site():
"""Load a Five/Zope site by finding and loading the appropriate site
configuration file."""
global _initialized
if _initialized:
return
_initialized = True
import Globals
Globals.INSTANCE_HOME
# load instance site configuration file
site_zcml = os.path.join(Globals.INSTANCE_HOME, "etc", "site.zcml")
import Zope2.utilities
zope_utilities = os.path.dirname(Zope2.utilities.__file__)
skel_site_zcml = os.path.join(zope_utilities, "skel", "etc", "site.zcml")
if os.path.exists(site_zcml):
file = site_zcml
else:
# check for zope installation home skel during running unit tests
file = skel_site_zcml
global _context
_context = xmlconfig.file(file)
def load_config(file, package=None, execute=True):
"""Load an additional ZCML file into the context.
Use with extreme care.
"""
global _context
_context = xmlconfig.file(file, package, _context, execute=execute)
def load_string(s):
"""Load a snipped of ZCML into the context.
Use with extreme care.
"""
global _context
_context = xmlconfig.string(s, _context)
# clean up code
def cleanUp():
global _context
_context = None
from zope.testing.cleanup import addCleanUp
addCleanUp(cleanUp)
del addCleanUp
from Zope2.App.zcml import load_site
from Zope2.App.zcml import load_config
from Zope2.App.zcml import load_string
from Zope2.App.zcml import cleanUp
......@@ -32,7 +32,7 @@ from OFS.tests.testCopySupport import CopySupportTestBase
from OFS.tests.testCopySupport import UnitTestSecurityPolicy
from OFS.tests.testCopySupport import UnitTestUser
from Products.Five import zcml
from Zope2.App import zcml
from Products.StandardCacheManagers.RAMCacheManager import RAMCacheManager
from Products.StandardCacheManagers.AcceleratedHTTPCacheManager \
import AcceleratedHTTPCacheManager
......
......@@ -52,7 +52,7 @@ tearDown = tearDown()
del ps
# For convenience
from Products.Five import zcml
from Zope2.App import zcml
def callZCML(zcml_callback):
......
......@@ -15,11 +15,14 @@
$Id$
"""
import sys
from unittest import TestSuite
from Testing import ZopeTestCase
from Testing.ZopeTestCase import ZopeLite
from Testing.ZopeTestCase import ZopeDocTestSuite
from Products.Five import zcml
from Zope2.App import zcml
from zope.testing import cleanup
import Products
......@@ -29,7 +32,7 @@ def testInstallPackage():
Test if installPackage works.
>>> from Testing import ZopeTestCase
>>> from Products.Five import zcml
>>> from Zope2.App import zcml
Register testpackage
......@@ -84,8 +87,7 @@ class TestClass(ZopeTestCase.FunctionalTestCase):
def afterSetUp(self):
cleanup.cleanUp()
zcml._initialized = False
zcml.load_site()
zcml.load_site(force=True)
self.saved = sys.path[:]
sys.path.append(ZopeTestCase.__path__[0])
......
##############################################################################
#
# Copyright (c) 2004, 2005 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
from zope.component import getUtility
from zope.interface import implements
from zope.schema.interfaces import IVocabularyFactory
from zope.schema.interfaces import IVocabularyRegistry
class Zope2VocabularyRegistry(object):
"""IVocabularyRegistry that supports global and local utilities.
"""
implements(IVocabularyRegistry)
__slots__ = ()
def get(self, context, name):
"""See zope.schema.interfaces.IVocabularyRegistry.
"""
factory = getUtility(IVocabularyFactory, name)
return factory(context)
......@@ -14,6 +14,10 @@
"""
from zope.component import queryMultiAdapter
from zope.event import notify
from zope.processlifetime import DatabaseOpened
from zope.schema.vocabulary import setVocabularyRegistry
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from Acquisition import aq_acquire
......@@ -22,10 +26,8 @@ from Acquisition import aq_inner
from Acquisition import aq_parent
from App.config import getConfiguration
from time import asctime
from types import StringType, ListType
from zExceptions import upgradeException
from zExceptions import Redirect
from zExceptions import Unauthorized
from ZODB.POSException import ConflictError
import transaction
import AccessControl.User
......@@ -40,9 +42,6 @@ import App.ZApplication
import Zope2
import ZPublisher
from zope.event import notify
from zope.processlifetime import DatabaseOpened
app = None
startup_time = asctime()
......@@ -92,7 +91,7 @@ def startup():
from ZODB.ActivityMonitor import ActivityMonitor
DB.setActivityMonitor(ActivityMonitor())
Globals.DB = DB # Ick, this is temporary until we come up with some registry
Globals.DB = DB
Zope2.DB = DB
# Hook for providing multiple transaction object manager undo support:
......@@ -105,6 +104,14 @@ def startup():
# "Log on" as system user
newSecurityManager(None, AccessControl.User.system)
# Set up the CA
from .zcml import load_site
load_site()
# Set up Zope2 specific vocabulary registry
from .schema import Zope2VocabularyRegistry
setVocabularyRegistry(Zope2VocabularyRegistry())
# Set up the "app" object that automagically opens
# connections
app = App.ZApplication.ZApplicationWrapper(
......@@ -138,7 +145,10 @@ def validated_hook(request, user):
class RequestContainer(ExtensionClass.Base):
def __init__(self,r): self.REQUEST=r
def __init__(self, r):
self.REQUEST=r
class ZPublisherExceptionHook:
......@@ -215,7 +225,7 @@ class ZPublisherExceptionHook:
return response
if (published is None or published is app or
type(published) is ListType):
isinstance(published, list)):
# At least get the top-level object
published=app.__bobo_traverse__(REQUEST).__of__(
RequestContainer(REQUEST))
......
##############################################################################
#
# Copyright (c) 2004, 2005 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ZCML machinery
"""
import os
import os.path
from zope.configuration import xmlconfig
_initialized = False
_context = None
def load_site(force=False):
"""Load a Zope site by finding and loading the appropriate site
configuration file."""
global _initialized
if _initialized and not force:
return
_initialized = True
import Globals
Globals.INSTANCE_HOME
# load instance site configuration file
site_zcml = os.path.join(Globals.INSTANCE_HOME, "etc", "site.zcml")
if not os.path.exists(site_zcml):
# check for zope installation home skel during running unit tests
import Zope2.utilities
zope_utils = os.path.dirname(Zope2.utilities.__file__)
site_zcml = os.path.join(zope_utils, "skel", "etc", "site.zcml")
global _context
_context = xmlconfig.file(site_zcml)
def load_config(config, package=None, execute=True):
"""Load an additional ZCML file into the context.
Use with extreme care.
"""
global _context
_context = xmlconfig.file(config, package, _context, execute=execute)
def load_string(s):
"""Load a snipped of ZCML into the context.
Use with extreme care.
"""
global _context
_context = xmlconfig.string(s, _context)
# clean up code
def cleanUp():
global _context
_context = None
from zope.testing.cleanup import addCleanUp
addCleanUp(cleanUp)
del addCleanUp
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