[Zope3-checkins] CVS: Zope3/src/zope/app/services - configuration.py:1.34
Guido van Rossum
guido@python.org
Thu, 12 Jun 2003 13:04:15 -0400
Update of /cvs-repository/Zope3/src/zope/app/services
In directory cvs.zope.org:/tmp/cvs-serv25618/services
Modified Files:
configuration.py
Log Message:
Use/allow relative paths in ComponentConfiguration subclasses.
Existing absolute paths will continue to work, but all newly created
ComponentConfiguration subclass instances will use a path relative to
the site management folder containing the configured object -- i.e.,
this is just the object's name. Fixed all places where I've seen
absolute paths used. (Still to do: use relative paths for references
*to* the configuration object as well; these occur in registries, and
are also used by the IUseConfigurable machinery and by dependencies.)
=== Zope3/src/zope/app/services/configuration.py 1.33 => 1.34 ===
--- Zope3/src/zope/app/services/configuration.py:1.33 Wed Jun 11 13:25:02 2003
+++ Zope3/src/zope/app/services/configuration.py Thu Jun 12 13:03:44 2003
@@ -50,14 +50,14 @@
from zope.app.interfaces.services.configuration import Unregistered
from zope.app.interfaces.services.configuration import Registered, Active
from zope.app.traversing import getRoot, getPath, traverse
-from zope.app.traversing import canonicalPath
from zope.component import getAdapter, queryAdapter
from zope.component import getServiceManager
from zope.app.context import ContextWrapper
-from zope.context import ContextMethod, ContextDescriptor
+from zope.context import ContextMethod, ContextDescriptor, getWrapperContainer
from zope.proxy import removeAllProxies
from zope.security.checker import InterfaceChecker
from zope.security.proxy import Proxy, trustedRemoveSecurityProxy
+from zope.proxy import getProxiedObject
class ConfigurationStatusProperty(ContextDescriptor):
@@ -355,11 +355,17 @@
self.permission = permission
def implementationSummary(self):
- return canonicalPath(self.componentPath)
+ return self.componentPath
def getComponent(wrapped_self):
service_manager = getServiceManager(wrapped_self)
+ # The user of the configuration object may not have permission
+ # to traverse to the component. Yet they should be able to
+ # get it by calling getComponent() on a configuration object
+ # for which they do have permission. What they get will be
+ # wrapped in a security proxy of course. Hence:
+
# We have to be clever here. We need to do an honest to
# god unrestricted traveral, which means we have to
# traverse from an unproxied object. But, it's not enough
@@ -369,9 +375,20 @@
# traverses from there, so we need to make sure the
# physical root isn't proxied.
- # get the root and unproxy it.
+ path = wrapped_self.componentPath
+ # Get the root and unproxy it
root = removeAllProxies(getRoot(service_manager))
- component = traverse(root, wrapped_self.componentPath)
+ if path.startswith("/"):
+ # Absolute path
+ component = traverse(root, path)
+ else:
+ # Relative path.
+ # XXX We do a strange little dance because we want the
+ # context to inherit the unproxied root, and this is
+ # the only way to keep it.
+ ancestor = getWrapperContainer(getWrapperContainer(wrapped_self))
+ ancestor = traverse(root, getPath(ancestor))
+ component = traverse(ancestor, path)
if wrapped_self.permission:
if type(component) is Proxy:
@@ -712,11 +729,9 @@
The file representation of a configuration object is an XML pickle
for a modified version of the instance dict. In this version of
- the instance dict, the componentPath attribute is converted to a
- path relative to the highest level site management folder
- containing the configuration object, and the __annotations__
- attribute is omitted, because annotations are already stored on
- the filesystem in a different way (in @@Zope/Annotations/<file>).
+ the instance dict, the __annotations__ attribute is omitted,
+ because annotations are already stored on the filesystem in a
+ different way (in @@Zope/Annotations/<file>).
"""
implements(IObjectFile)
@@ -731,9 +746,6 @@
obj = removeAllProxies(self.context)
ivars = {}
ivars.update(obj.__getstate__())
- cpname = "componentPath"
- if cpname in ivars:
- ivars[cpname] = self._make_relative_path(ivars[cpname])
aname = "__annotations__"
if aname in ivars:
del ivars[aname]
@@ -743,32 +755,4 @@
"""See IObjectEntry."""
obj = removeAllProxies(self.context)
ivars = loads(body)
- cpname = "componentPath"
- if cpname in ivars:
- ivars[cpname] = self._make_absolute_path(ivars[cpname])
obj.__setstate__(ivars)
-
- def _make_relative_path(self, apath):
- if apath.startswith("/"):
- prefix = self._get_prefix()
- if prefix and apath.startswith(prefix):
- apath = apath[len(prefix):]
- while apath.startswith("/"):
- apath = apath[1:]
- return apath
-
- def _make_absolute_path(self, rpath):
- if not rpath.startswith("/"):
- prefix = self._get_prefix()
- if prefix:
- rpath = prefix + rpath
- return rpath
-
- def _get_prefix(self):
- parts = getPath(self.context).split("/")
- try:
- i = parts.index("++etc++site")
- except ValueError:
- return None
- else:
- return "/".join(parts[:i+2]) + "/"