[Checkins] SVN: five.localsitemanager/trunk/src/five/localsitemanager/ Implemented the lookup logic to use the site manager a utility was registered in as the Acquisition context.

Hanno Schlichting plone at hannosch.info
Wed Jun 6 11:37:02 EDT 2007


Log message for revision 76427:
  Implemented the lookup logic to use the site manager a utility was registered in as the Acquisition context.
  

Changed:
  U   five.localsitemanager/trunk/src/five/localsitemanager/__init__.py
  U   five.localsitemanager/trunk/src/five/localsitemanager/registry.py
  A   five.localsitemanager/trunk/src/five/localsitemanager/utils.py

-=-
Modified: five.localsitemanager/trunk/src/five/localsitemanager/__init__.py
===================================================================
--- five.localsitemanager/trunk/src/five/localsitemanager/__init__.py	2007-06-06 15:11:26 UTC (rev 76426)
+++ five.localsitemanager/trunk/src/five/localsitemanager/__init__.py	2007-06-06 15:37:01 UTC (rev 76427)
@@ -1,11 +1,11 @@
-from Acquisition import aq_parent, aq_inner
-from zope import interface
+from Acquisition import aq_base
 from zope.component.globalregistry import base
 from zope.traversing.interfaces import IContainmentRoot
 from zope.app.component.interfaces import ISite
 from five.localsitemanager.registry import PersistentComponents
+from five.localsitemanager.utils import get_parent
 from Products.Five.component.interfaces import IObjectManagerSite
-from Products.Five.component import enableSite, disableSite
+from Products.Five.component import enableSite
 
 def make_site(obj, iface=ISite):
     """Give the specified object required qualities to identify it as a proper
@@ -29,6 +29,7 @@
 
     components = PersistentComponents(name=name, bases=(next,))
     obj.setSiteManager(components)
+    components.__parent__ = aq_base(obj)
 
 def make_objectmanager_site(obj):
     """Just a bit of sugar coating to make an unnofficial objectmanager
@@ -37,30 +38,7 @@
     
     make_site(obj, IObjectManagerSite)
 
-def get_parent(obj):
-    """Returns the container the object was traversed via.  This
-    is a version of zope.traversing.api.getParent that is designed to
-    handle acquisition as well.
 
-    Returns None if the object is a containment root.
-    Raises TypeError if the object doesn't have enough context to get the
-    parent.
-    """
-    
-    if IContainmentRoot.providedBy(obj):
-        return None
-    
-    parent = getattr(obj, '__parent__', None)
-    if parent is not None:
-        return parent
-
-    parent = aq_parent(aq_inner(obj))
-    if parent is not None:
-        return parent
-
-    raise TypeError("Not enough context information to get parent", obj)
-
-
 def find_next_sitemanager(site):
     """Find the closest sitemanager that is not the specified site's
     sitemanager.

Modified: five.localsitemanager/trunk/src/five/localsitemanager/registry.py
===================================================================
--- five.localsitemanager/trunk/src/five/localsitemanager/registry.py	2007-06-06 15:11:26 UTC (rev 76426)
+++ five.localsitemanager/trunk/src/five/localsitemanager/registry.py	2007-06-06 15:37:01 UTC (rev 76427)
@@ -1,6 +1,6 @@
 import Acquisition
 from zope.app.component.hooks import getSite
-from zope.component.interfaces import ComponentLookupError
+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
@@ -10,6 +10,8 @@
 from zope.interface.adapter import _subscriptions
 import OFS.ObjectManager
 
+from five.localsitemanager.utils import get_parent
+
 _marker = object()
 
 class FiveVerifyingAdapterLookup(VerifyingAdapterLookup):
@@ -87,6 +89,13 @@
 
     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.
@@ -94,7 +103,7 @@
 
     # 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
+    # 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
@@ -103,7 +112,18 @@
     # local) components.
 
     if registry.__bases__ and Acquisition.interfaces.IAcquirer.providedBy(comp):
-        parent = getSite()
+        current_site = getSite()
+        registry_site = Acquisition.aq_base(registry.__parent__)
+        if not ISite.providedBy(registry_site):
+            registry_site = registry_site.__parent__
+
+        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')
 
@@ -133,6 +153,7 @@
     def _init_registries(self):
         self.adapters = PersistentAdapterRegistry()
         self.utilities = FivePersistentAdapterRegistry()
+        self.utilities.__parent__ = self
 
     def registeredUtilities(self):
         for ((provided, name), (component, info)

Added: five.localsitemanager/trunk/src/five/localsitemanager/utils.py
===================================================================
--- five.localsitemanager/trunk/src/five/localsitemanager/utils.py	                        (rev 0)
+++ five.localsitemanager/trunk/src/five/localsitemanager/utils.py	2007-06-06 15:37:01 UTC (rev 76427)
@@ -0,0 +1,27 @@
+from zope.traversing.interfaces import IContainmentRoot
+
+from Acquisition import aq_parent, aq_inner
+
+
+def get_parent(obj):
+    """Returns the container the object was traversed via.  This
+    is a version of zope.traversing.api.getParent that is designed to
+    handle acquisition as well.
+
+    Returns None if the object is a containment root.
+    Raises TypeError if the object doesn't have enough context to get the
+    parent.
+    """
+    
+    if IContainmentRoot.providedBy(obj):
+        return None
+    
+    parent = getattr(obj, '__parent__', None)
+    if parent is not None:
+        return parent
+
+    parent = aq_parent(aq_inner(obj))
+    if parent is not None:
+        return parent
+
+    raise TypeError("Not enough context information to get parent", obj)


Property changes on: five.localsitemanager/trunk/src/five/localsitemanager/utils.py
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Checkins mailing list