[Checkins] SVN: Products.GenericSetup/trunk/Products/GenericSetup/
Introduced a new IComponentsHandlerBlacklist interface. You
can register named utilities for it and provide sequences of
interfaces which should not be handled by the standard
components registry adapter. This allows more specialized
export/import handlers to take full control over the
components they care about.
Hanno Schlichting
plone at hannosch.info
Thu Apr 10 15:08:46 EDT 2008
Log message for revision 85220:
Introduced a new IComponentsHandlerBlacklist interface. You can register named utilities for it and provide sequences of interfaces which should not be handled by the standard components registry adapter. This allows more specialized export/import handlers to take full control over the components they care about.
Changed:
U Products.GenericSetup/trunk/Products/GenericSetup/CHANGES.txt
U Products.GenericSetup/trunk/Products/GenericSetup/components.py
U Products.GenericSetup/trunk/Products/GenericSetup/interfaces.py
U Products.GenericSetup/trunk/Products/GenericSetup/tests/test_components.py
-=-
Modified: Products.GenericSetup/trunk/Products/GenericSetup/CHANGES.txt
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/CHANGES.txt 2008-04-10 15:01:57 UTC (rev 85219)
+++ Products.GenericSetup/trunk/Products/GenericSetup/CHANGES.txt 2008-04-10 19:08:46 UTC (rev 85220)
@@ -2,6 +2,12 @@
GenericSetup 1.5.0 (unreleased)
+ - Introduced a new IComponentsHandlerBlacklist interface. You can register
+ named utilities for it and provide sequences of interfaces which should
+ not be handled by the standard components registry adapter. This allows
+ more specialized export/import handlers to take full control over the
+ components they care about.
+
- When loading multiple profiles reload the list of steps to use after
each import. https://bugs.launchpad.net/zope-cmf/+bug/213905
Modified: Products.GenericSetup/trunk/Products/GenericSetup/components.py
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/components.py 2008-04-10 15:01:57 UTC (rev 85219)
+++ Products.GenericSetup/trunk/Products/GenericSetup/components.py 2008-04-10 19:08:46 UTC (rev 85220)
@@ -18,6 +18,7 @@
from operator import itemgetter
from zope.component import adapts
+from zope.component import getAllUtilitiesRegisteredFor
from zope.component import getSiteManager
from zope.component import queryMultiAdapter
from zope.component.interfaces import IComponentRegistry
@@ -25,13 +26,16 @@
from Acquisition import aq_base
from Acquisition import aq_parent
-from interfaces import IBody
-from interfaces import ISetupEnviron
-from utils import XMLAdapterBase
-from utils import _getDottedName
-from utils import _resolveDottedName
+from Products.GenericSetup.interfaces import IBody
+from Products.GenericSetup.interfaces import IComponentsHandlerBlacklist
+from Products.GenericSetup.interfaces import ISetupEnviron
+from Products.GenericSetup.utils import XMLAdapterBase
+from Products.GenericSetup.utils import _getDottedName
+from Products.GenericSetup.utils import _resolveDottedName
+BLACKLIST_SELF = _getDottedName(IComponentsHandlerBlacklist)
+
class ComponentRegistryXMLAdapter(XMLAdapterBase):
"""XML im- and exporter for a local component registry.
@@ -43,6 +47,14 @@
name = 'componentregistry'
+ def _constructBlacklist(self):
+ blacklist = set((BLACKLIST_SELF, ))
+ utils = getAllUtilitiesRegisteredFor(IComponentsHandlerBlacklist)
+ for util in utils:
+ names = [_getDottedName(i) for i in util.getExcludedInterfaces()]
+ blacklist.update(names)
+ return blacklist
+
def _exportNode(self):
node = self._doc.createElement('componentregistry')
fragment = self._doc.createDocumentFragment()
@@ -78,12 +90,15 @@
def _purgeAdapters(self):
registrations = tuple(self.context.registeredAdapters())
-
+ blacklist = self._constructBlacklist()
+
for registration in registrations:
factory = registration.factory
required = registration.required
provided = registration.provided
name = registration.name
+ if _getDottedName(provided) in blacklist:
+ continue
self.context.unregisterAdapter(factory=factory,
required=required,
@@ -92,19 +107,29 @@
def _purgeUtilities(self):
registrations = tuple(self.context.registeredUtilities())
-
+ blacklist = self._constructBlacklist()
+
for registration in registrations:
provided = registration.provided
name = registration.name
+ if _getDottedName(provided) in blacklist:
+ continue
self.context.unregisterUtility(provided=provided, name=name)
def _initAdapters(self, node):
+ blacklist = self._constructBlacklist()
+
for child in node.childNodes:
if child.nodeName != 'adapter':
continue
factory = _resolveDottedName(child.getAttribute('factory'))
- provided = _resolveDottedName(child.getAttribute('provides'))
+
+ provided = child.getAttribute('provides')
+ if provided in blacklist:
+ continue
+
+ provided = _resolveDottedName(provided)
name = unicode(str(child.getAttribute('name')))
for_ = child.getAttribute('for_')
@@ -127,11 +152,17 @@
def _initUtilities(self, node):
site = self._getSite()
+ blacklist = self._constructBlacklist()
+
for child in node.childNodes:
if child.nodeName != 'utility':
continue
- provided = _resolveDottedName(child.getAttribute('interface'))
+ provided = child.getAttribute('interface')
+ if provided in blacklist:
+ continue
+
+ provided = _resolveDottedName(provided)
name = unicode(str(child.getAttribute('name')))
component = child.getAttribute('component')
@@ -178,8 +209,12 @@
for reg in self.context.registeredAdapters() ]
registrations.sort(key=itemgetter('name'))
registrations.sort(key=itemgetter('provided'))
+ blacklist = self._constructBlacklist()
for reg_info in registrations:
+ if reg_info['provided'] in blacklist:
+ continue
+
child = self._doc.createElement('adapter')
for_ = u''
@@ -206,10 +241,13 @@
registrations.sort(key=itemgetter('name'))
registrations.sort(key=itemgetter('provided'))
site = aq_base(self._getSite())
+ blacklist = self._constructBlacklist()
for reg_info in registrations:
+ if reg_info['provided'] in blacklist:
+ continue
+
child = self._doc.createElement('utility')
-
child.setAttribute('interface', reg_info['provided'])
if reg_info['name']:
Modified: Products.GenericSetup/trunk/Products/GenericSetup/interfaces.py
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/interfaces.py 2008-04-10 15:01:57 UTC (rev 85219)
+++ Products.GenericSetup/trunk/Products/GenericSetup/interfaces.py 2008-04-10 19:08:46 UTC (rev 85220)
@@ -849,3 +849,15 @@
tool = Attribute("The tool which is performing the import")
+
+class IComponentsHandlerBlacklist(Interface):
+ """ Interface for named utilities which can exclude specified interfaces
+ from being handled by the components export and import handlers.
+ """
+
+ def getExcludedInterfaces():
+ """ Return a sequence of interfaces.
+
+ Objects providing any of the returned interfaces should be ignored by
+ the export and import handlers.
+ """
Modified: Products.GenericSetup/trunk/Products/GenericSetup/tests/test_components.py
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/tests/test_components.py 2008-04-10 15:01:57 UTC (rev 85219)
+++ Products.GenericSetup/trunk/Products/GenericSetup/tests/test_components.py 2008-04-10 19:08:46 UTC (rev 85220)
@@ -26,13 +26,18 @@
from Products.Five.component import enableSite
from Products.Five.component.interfaces import IObjectManagerSite
from zope.app.component.hooks import setSite, clearSite, setHooks
+from zope.component import getMultiAdapter
+from zope.component import getGlobalSiteManager
from zope.component import getSiteManager
from zope.component import queryUtility
from zope.component.globalregistry import base
from zope.interface import implements
from zope.interface import Interface
+from Products.GenericSetup.interfaces import IBody
+from Products.GenericSetup.interfaces import IComponentsHandlerBlacklist
from Products.GenericSetup.testing import BodyAdapterTestCase
+from Products.GenericSetup.testing import DummySetupEnviron
from Products.GenericSetup.testing import ExportImportZCMLLayer
try:
@@ -55,6 +60,12 @@
def verify():
"""Returns True."""
+class IDummyInterface2(Interface):
+ """A second dummy interface."""
+
+ def verify():
+ """Returns True."""
+
class DummyUtility(object):
"""A dummy utility."""
@@ -81,7 +92,7 @@
class DummyTool2(SimpleItem):
"""A second dummy tool."""
- implements(IDummyInterface)
+ implements(IDummyInterface2)
id = 'dummy_tool2'
meta_type = 'dummy tool2'
@@ -94,6 +105,15 @@
InitializeClass(DummyTool2)
+class DummyBlacklist(object):
+ """A blacklist."""
+
+ implements(IComponentsHandlerBlacklist)
+
+ def getExcludedInterfaces(self):
+ return (IDummyInterface, )
+
+
_COMPONENTS_BODY = """\
<?xml version="1.0"?>
<componentregistry>
@@ -105,11 +125,11 @@
interface="Products.GenericSetup.tests.test_components.IDummyInterface"
object="dummy_tool"/>
<utility name="dummy tool name2"
- interface="Products.GenericSetup.tests.test_components.IDummyInterface"
+ interface="Products.GenericSetup.tests.test_components.IDummyInterface2"
object="dummy_tool2"/>
<utility name="foo"
factory="Products.GenericSetup.tests.test_components.DummyUtility"
- interface="Products.GenericSetup.tests.test_components.IDummyInterface"/>
+ interface="Products.GenericSetup.tests.test_components.IDummyInterface2"/>
</utilities>
</componentregistry>
"""
@@ -126,16 +146,16 @@
def _populate(self, obj):
obj.registerUtility(DummyUtility(), IDummyInterface)
- obj.registerUtility(DummyUtility(), IDummyInterface, name=u'foo')
+ obj.registerUtility(DummyUtility(), IDummyInterface2, name=u'foo')
tool = aq_base(obj.aq_parent['dummy_tool'])
obj.registerUtility(tool, IDummyInterface, name=u'dummy tool name')
tool2 = aq_base(obj.aq_parent['dummy_tool2'])
- obj.registerUtility(tool2, IDummyInterface, name=u'dummy tool name2')
+ obj.registerUtility(tool2, IDummyInterface2, name=u'dummy tool name2')
def _verifyImport(self, obj):
- util = queryUtility(IDummyInterface, name=u'foo')
+ util = queryUtility(IDummyInterface2, name=u'foo')
self.failUnless(IDummyInterface.providedBy(util))
self.failUnless(util.verify())
@@ -153,8 +173,8 @@
self.assertEqual(tool.meta_type, 'dummy tool')
self.assertEquals(repr(aq_base(util)), repr(aq_base(tool)))
- util = queryUtility(IDummyInterface, name='dummy tool name2')
- self.failUnless(IDummyInterface.providedBy(util))
+ util = queryUtility(IDummyInterface2, name='dummy tool name2')
+ self.failUnless(IDummyInterface2.providedBy(util))
self.failUnless(util.verify())
self.assertEqual(util.meta_type, 'dummy tool2')
@@ -163,6 +183,62 @@
self.assertEqual(tool.meta_type, 'dummy tool2')
self.assertEquals(repr(aq_base(util)), repr(aq_base(tool)))
+ def test_blacklist_get(self):
+ obj = self._obj
+ self._populate(obj)
+
+ # Register our blacklist
+ gsm = getGlobalSiteManager()
+ gsm.registerUtility(DummyBlacklist(),
+ IComponentsHandlerBlacklist,
+ name=u'dummy')
+
+ context = DummySetupEnviron()
+ adapted = getMultiAdapter((obj, context), IBody)
+
+ body = adapted.body
+ self.failIf('IComponentsHandlerBlacklist' in body)
+ self.failIf('test_components.IDummyInterface"' in body)
+
+ def test_blacklist_set(self):
+ obj = self._obj
+ # Register our blacklist
+ gsm = getGlobalSiteManager()
+ gsm.registerUtility(DummyBlacklist(),
+ IComponentsHandlerBlacklist,
+ name=u'dummy')
+
+ context = DummySetupEnviron()
+ adapted = getMultiAdapter((obj, context), IBody)
+ adapted.body = self._BODY
+
+ util = queryUtility(IDummyInterface2, name=u'foo')
+ self.failUnless(IDummyInterface.providedBy(util))
+ self.failUnless(util.verify())
+ util = queryUtility(IDummyInterface)
+ self.failUnless(util is None)
+
+ # now in update mode
+ context._should_purge = False
+ adapted = getMultiAdapter((obj, context), IBody)
+ adapted.body = self._BODY
+
+ util = queryUtility(IDummyInterface2, name=u'foo')
+ self.failUnless(IDummyInterface.providedBy(util))
+ self.failUnless(util.verify())
+ util = queryUtility(IDummyInterface)
+ self.failUnless(util is None)
+
+ # and again in update mode
+ adapted = getMultiAdapter((obj, context), IBody)
+ adapted.body = self._BODY
+
+ util = queryUtility(IDummyInterface2, name=u'foo')
+ self.failUnless(IDummyInterface.providedBy(util))
+ self.failUnless(util.verify())
+ util = queryUtility(IDummyInterface)
+ self.failUnless(util is None)
+
def setUp(self):
# Create and enable a local component registry
site = Folder()
@@ -182,7 +258,12 @@
def tearDown(self):
clearSite()
+ # Make sure our global utility is gone again
+ gsm = getGlobalSiteManager()
+ gsm.unregisterUtility(provided=IComponentsHandlerBlacklist,
+ name=u'dummy')
+
if PersistentComponents is not None:
def test_suite():
# reimport to make sure tests are run from Products
More information about the Checkins
mailing list