[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