[Checkins] SVN: Products.GenericSetup/trunk/Products/GenericSetup/ Handle utility factories cleanly if zope.component >=3.5.0 is used. I'm assuming my utility-registration branch gets merged there but I am feeling confident today.

Wichert Akkerman wichert at wiggy.net
Wed Jul 23 10:15:31 EDT 2008


Log message for revision 88762:
  Handle utility factories cleanly if zope.component >=3.5.0 is used. I'm assuming my utility-registration branch gets merged there but I am feeling confident today.

Changed:
  U   Products.GenericSetup/trunk/Products/GenericSetup/CHANGES.txt
  U   Products.GenericSetup/trunk/Products/GenericSetup/components.py

-=-
Modified: Products.GenericSetup/trunk/Products/GenericSetup/CHANGES.txt
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/CHANGES.txt	2008-07-23 14:10:57 UTC (rev 88761)
+++ Products.GenericSetup/trunk/Products/GenericSetup/CHANGES.txt	2008-07-23 14:15:30 UTC (rev 88762)
@@ -4,6 +4,8 @@
 GenericSetup 1.5.0 (unreleased)
 -------------------------------
 
+- Handle utility factories cleanly if zope.component >=3.5.0 is used.
+ 
 - tool and utils: Removed deprecated code.
 
 - Update PropertyManagerHelpers to make it possible to remove elements from a

Modified: Products.GenericSetup/trunk/Products/GenericSetup/components.py
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/components.py	2008-07-23 14:10:57 UTC (rev 88761)
+++ Products.GenericSetup/trunk/Products/GenericSetup/components.py	2008-07-23 14:15:30 UTC (rev 88762)
@@ -18,7 +18,7 @@
 from operator import itemgetter
 
 from zope.component import adapts
-from zope.component import getAllUtilitiesRegisteredFor
+from zope.component import getUtilitiesFor
 from zope.component import getSiteManager
 from zope.component import queryMultiAdapter
 from zope.component.interfaces import IComponentRegistry
@@ -49,8 +49,8 @@
 
     def _constructBlacklist(self):
         blacklist = set((BLACKLIST_SELF, ))
-        utils = getAllUtilitiesRegisteredFor(IComponentsHandlerBlacklist)
-        for util in utils:
+        utils = getUtilitiesFor(IComponentsHandlerBlacklist)
+        for _, util in utils:
             names = [_getDottedName(i) for i in util.getExcludedInterfaces()]
             blacklist.update(names)
         return blacklist
@@ -154,6 +154,8 @@
         site = self._getSite()
         blacklist = self._constructBlacklist()
 
+        current_utilities = self.context.registeredUtilities()
+
         for child in node.childNodes:
             if child.nodeName != 'utility':
                 continue
@@ -171,6 +173,11 @@
             factory = child.getAttribute('factory')
             factory = factory and _resolveDottedName(factory) or None
 
+            if component and factory:
+                raise ValueError, "Can not specify both a factory and a " \
+                                  "component in a utility registration."
+
+
             obj_path = child.getAttribute('object')
             if not component and not factory and obj_path is not None:
                 # Support for registering the site itself
@@ -193,8 +200,20 @@
                                          % (repr(obj), obj_path, repr(site)))
             elif component:
                 self.context.registerUtility(component, provided, name)
-            elif factory is not None:
-                self.context.registerUtility(factory(), provided, name)
+            elif factory:
+                current = [ utility for utility in current_utilities
+                                    if utility.provided==provided and 
+                                       utility.name==name ]
+                assert len(current) <=1
+
+                if current and getattr(current[0], "factory", None)==factory:
+                    continue
+
+                try:
+                    self.context.registerUtility(None, provided, name, factory=factory)
+                except TypeError:
+                    # zope.component < 3.5.0
+                    self.context.registerUtility(factory(), provided, name)
             else:
                 self._logger.warning("Invalid utility registration for "
                                      "interface %s" % provided)
@@ -235,9 +254,10 @@
         fragment = self._doc.createDocumentFragment()
 
         registrations = [ {'component': reg.component,
+                           'factory' : getattr(reg, 'factory', None),
                            'provided': _getDottedName(reg.provided),
                            'name': reg.name}
-                          for reg in self.context.registeredUtilities() ]
+                           for reg in self.context.registeredUtilities() ]
         registrations.sort(key=itemgetter('name'))
         registrations.sort(key=itemgetter('provided'))
         site = aq_base(self._getSite())
@@ -253,21 +273,24 @@
             if reg_info['name']:
                 child.setAttribute('name', reg_info['name'])
 
-            comp = reg_info['component']
-            # check if the component is acquisition wrapped. If it is, export
-            # an object reference instead of a factory reference
-            if getattr(comp, 'aq_base', None) is not None:
-                if aq_base(comp) is site:
-                    child.setAttribute('object', '')
-                elif hasattr(aq_base(comp), 'getId'):
-                    child.setAttribute('object', comp.getId())
+            if reg_info['factory'] is not None:
+                child.setAttribute('factory', _getDottedName(reg_info['factory']))
+            else:
+                comp = reg_info['component']
+                # check if the component is acquisition wrapped. If it is, export
+                # an object reference instead of a factory reference
+                if getattr(comp, 'aq_base', None) is not None:
+                    if aq_base(comp) is site:
+                        child.setAttribute('object', '')
+                    elif hasattr(aq_base(comp), 'getId'):
+                        child.setAttribute('object', comp.getId())
+                    else:
+                        # This is a five.localsitemanager wrapped utility
+                        factory = _getDottedName(type(aq_base(comp)))
+                        child.setAttribute('factory', factory)
                 else:
-                    # This is a five.localsitemanager wrapped utility
-                    factory = _getDottedName(type(aq_base(comp)))
+                    factory = _getDottedName(type(comp))
                     child.setAttribute('factory', factory)
-            else:
-                factory = _getDottedName(type(comp))
-                child.setAttribute('factory', factory)
 
             fragment.appendChild(child)
 
@@ -304,3 +327,4 @@
         if body is not None:
             context.writeDataFile('componentregistry.xml', body,
                                   exporter.mime_type)
+



More information about the Checkins mailing list