[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