[Checkins] SVN: five.localsitemanager/trunk/src/five/localsitemanager/registry.py - back to revision 72968

Yvo Schubbe y.2007- at wcm-solutions.de
Thu Jun 7 17:16:57 EDT 2007


Log message for revision 76481:
  - back to revision 72968
  
  (We can't cache wrapped utilities across request boundaries because some tools use self.REQUEST. So REQUEST has to be part of the wrapper, making it REQUEST-specific.)

Changed:
  U   five.localsitemanager/trunk/src/five/localsitemanager/registry.py

-=-
Modified: five.localsitemanager/trunk/src/five/localsitemanager/registry.py
===================================================================
--- five.localsitemanager/trunk/src/five/localsitemanager/registry.py	2007-06-07 21:08:08 UTC (rev 76480)
+++ five.localsitemanager/trunk/src/five/localsitemanager/registry.py	2007-06-07 21:16:56 UTC (rev 76481)
@@ -1,168 +1,69 @@
 import Acquisition
-from zope.app.component.hooks import getSite
-from zope.app.component.interfaces import ISite
-from zope.component.persistentregistry import PersistentAdapterRegistry
-from zope.component.persistentregistry import PersistentComponents
-from zope.component.registry import UtilityRegistration
-from zope.interface.adapter import VerifyingAdapterLookup
-from zope.interface.adapter import _lookup
-from zope.interface.adapter import _lookupAll
-from zope.interface.adapter import _subscriptions
+from zope.component.interfaces import ComponentLookupError
+import zope.component.persistentregistry
 import OFS.ObjectManager
 
-from five.localsitemanager.utils import get_parent
-
 _marker = object()
 
-class FiveVerifyingAdapterLookup(VerifyingAdapterLookup):
+class PersistentComponents \
+          (zope.component.persistentregistry.PersistentComponents,
+           OFS.ObjectManager.ObjectManager):
+    """An implementation of a component registry that can be persisted
+    and looks like a standard ObjectManager.  It also ensures that all
+    utilities have the the parent of this site manager (which should be
+    the ISite) as their acquired parent.
+    """
 
-    def _uncached_lookup(self, required, provided, name=u''):
-        result = None
-        order = len(required)
-        for registry in self._registry.ro:
-            byorder = registry._adapters
-            if order >= len(byorder):
-                continue
+    def _wrap(self, comp):
+        """Return an aq wrapped component with the site as the parent but
+        only if the comp has an aq wrapper to begin with.
+        """
 
-            extendors = registry._v_lookup._extendors.get(provided)
-            if not extendors:
-                continue
+        # BBB: The primary reason for doing this sort of wrapping of
+        # returned utilities is to support CMF tool-like functionality where
+        # a tool expects it's aq_parent to be the portal object.  New code
+        # (ie new utilities) should not rely on this predictability to
+        # get the portal object and should search out an alternate means
+        # (possibly retrieve the ISiteRoot utility).  Although in most
+        # cases getting at the portal object shouldn't be the required pattern
+        # but instead looking up required functionality via other (possibly
+        # local) components.
 
-            components = byorder[order]
-            result = _lookup(components, required, extendors, name, 0,
-                             order)
-            if result is not None:
-                result = _wrap(result, registry)
-                break
+        if Acquisition.interfaces.IAcquirer.providedBy(comp):
+            parent = Acquisition.aq_parent(self)
+            if parent is None:
+                raise ValueError('Not enough context to acquire parent')
 
-        self._subscribe(*required)
+            base = Acquisition.aq_base(comp)
 
-        return result
-
-    def _uncached_lookupAll(self, required, provided):
-        order = len(required)
-        result = {}
-        for registry in reversed(self._registry.ro):
-            byorder = registry._adapters
-            if order >= len(byorder):
-                continue
-            extendors = registry._v_lookup._extendors.get(provided)
-            if not extendors:
-                continue
-            components = byorder[order]
-            tmp_result = {}
-            _lookupAll(components, required, extendors, tmp_result, 0, order)
-            for k, v in tmp_result.iteritems():
-                tmp_result[k] = _wrap(v, registry)
-            result.update(tmp_result)
-
-        self._subscribe(*required)
-
-        return tuple(result.iteritems())
-
-    def _uncached_subscriptions(self, required, provided):
-        order = len(required)
-        result = []
-        for registry in reversed(self._registry.ro):
-            byorder = registry._subscribers
-            if order >= len(byorder):
-                continue
-
-            if provided is None:
-                extendors = (provided, )
+            if base is not Acquisition.aq_base(parent):
+                # If the component is not the cmoponent registry container,
+                # wrap it in the parent
+                comp = base.__of__(parent)
             else:
-                extendors = registry._v_lookup._extendors.get(provided)
-                if extendors is None:
-                    continue
+                # If the component happens to be the component registry
+                # container we are looking up a ISiteRoot.
+                # We are not wrapping it in itself but in its own parent
+                comp = base.__of__(Acquisition.aq_parent(parent))
 
-            tmp_result = []
-            _subscriptions(byorder[order], required, extendors, u'',
-                           result, 0, order)
-            result = [ _wrap(r, registry) for r in result ]
+        return comp
 
-        self._subscribe(*required)
+    def queryUtility(self, provided, name=u'', default=None):
+        comp = self.utilities.lookup((), provided, name, default)
+        if comp is not default:
+            comp = self._wrap(comp)
+        return comp
 
-        return result
+    def getUtility(self, provided, name=u''):
+        utility = self.queryUtility(provided, name, _marker)
+        if utility is _marker:
+            raise ComponentLookupError(provided, name)
+        return utility
 
+    def getUtilitiesFor(self, interface):
+        return ((name, self._wrap(utility))
+                for name, utility in self.utilities.lookupAll((), interface))
 
-class FivePersistentAdapterRegistry(PersistentAdapterRegistry):
-
-    LookupClass = FiveVerifyingAdapterLookup
-
-
-def _recurse_to_site(current, wanted):
-    if not Acquisition.aq_base(current) == wanted:
-        current = _recurse_to_site(get_parent(current), wanted)
-    return current
-
-
-def _wrap(comp, registry):
-    """Return an aq wrapped component with the site as the parent but
-    only if the comp has an aq wrapper to begin with.
-    """
-
-    # BBB: The primary reason for doing this sort of wrapping of
-    # returned utilities is to support CMF tool-like functionality where
-    # a tool expects its aq_parent to be the portal object. New code
-    # (ie new utilities) should not rely on this predictability to
-    # get the portal object and should search out an alternate means
-    # (possibly retrieve the ISiteRoot utility). Although in most
-    # cases getting at the portal object shouldn't be the required pattern
-    # but instead looking up required functionality via other (possibly
-    # local) components.
-
-    if registry.__bases__ and Acquisition.interfaces.IAcquirer.providedBy(comp):
-        current_site = getSite()
-        registry_site = Acquisition.aq_base(registry.__parent__)
-        if not ISite.providedBy(registry_site):
-            registry_site = registry_site.__parent__
-
-        if current_site is None:
-            # If no current site can be found, return utilities wrapped in
-            # the site they where registered in. We loose the whole aq chain
-            # here though
-            current_site = Acquisition.aq_base(registry_site)
-
-        parent = None
-
-        if current_site == registry_site:
-            parent = current_site
-        else:
-            parent = _recurse_to_site(current_site, registry_site)
-
-        if parent is None:
-            raise ValueError('Not enough context to acquire parent')
-
-        base = Acquisition.aq_base(comp)
-
-        if base is not Acquisition.aq_base(parent):
-            # If the component is not the component registry container,
-            # wrap it in the parent
-            comp = base.__of__(parent)
-        else:
-            # If the component happens to be the component registry
-            # container we are looking up a ISiteRoot.
-            # We are not wrapping it in itself but in its own parent
-            comp = base.__of__(Acquisition.aq_parent(parent))
-
-    return comp
-
-class PersistentComponents \
-          (PersistentComponents,
-           OFS.ObjectManager.ObjectManager):
-    """An implementation of a component registry that can be persisted
-    and looks like a standard ObjectManager.  It also ensures that all
-    utilities have the the parent of this site manager (which should be
-    the ISite) as their acquired parent.
-    """
-
-    def _init_registries(self):
-        self.adapters = PersistentAdapterRegistry()
-        self.utilities = FivePersistentAdapterRegistry()
-        self.utilities.__parent__ = self
-
-    def registeredUtilities(self):
-        for ((provided, name), (component, info)
-             ) in self._utility_registrations.iteritems():
-            yield UtilityRegistration(self, provided, name,
-                                      _wrap(component, self), info)
+    def getAllUtilitiesRegisteredFor(self, interface):
+        return (self._wrap(x)
+                for x in self.utilities.subscriptions((), interface))



More information about the Checkins mailing list