[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services/ObjectHub - IObjectHub.py:1.3 ObjectHub.py:1.3
Steve Alexander
steve@cat-box.net
Tue, 26 Nov 2002 14:02:49 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Services/ObjectHub
In directory cvs.zope.org:/tmp/cvs-serv9843/lib/python/Zope/App/OFS/Services/ObjectHub
Modified Files:
IObjectHub.py ObjectHub.py
Log Message:
Added a method to IObjectHub for querying the registrations.
Changed the implementatation and the contract so that locations are
canonical as tuples of unicodes rather than as unicodes.
=== Zope3/lib/python/Zope/App/OFS/Services/ObjectHub/IObjectHub.py 1.2 => 1.3 ===
--- Zope3/lib/python/Zope/App/OFS/Services/ObjectHub/IObjectHub.py:1.2 Mon Nov 11 03:35:28 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ObjectHub/IObjectHub.py Tue Nov 26 14:02:49 2002
@@ -100,18 +100,20 @@
"""Returns the hub id int that is mapped to the given location
or wrapped object.
- Location is either a string, or a sequence of strings.
- It must be absolute, so if it is a string it must start with a '/',
- and if it is a sequence, it must start with an empty string.
+ Location is either a unicode, or a tuple of unicodes, or an
+ ascii string, or a tuple of ascii strings.
+ (See Zope/App/Traversing/__init__.py)
+ It must be absolute, so if it is a string it must start with a u'/',
+ and if it is a tuple, it must start with an empty string.
- ('','whatever','whatever2')
- '/whatever/whatever2'
+ (u'',u'whatever',u'whatever2')
+ u'/whatever/whatever2'
If there is no hub id, raise Zope.Exceptions.NotFoundError.
"""
def getLocation(hubid):
- """Returns a location as a string.
+ """Returns a location as a tuple of unicodes.
If there is no location, raise Zope.Exceptions.NotFoundError.
"""
@@ -138,4 +140,16 @@
It also emits a HubIdObjectUnregisteredEvent.
If the hub id or location wasn't registered a
Zope.Exceptions.NotFoundError is raised.
- """
+ """
+
+ def numRegistrations():
+ """Returns the number of location<-->hubid registrations held.
+ """
+
+ def registrations(location='/'):
+ """Returns a sequence of the registrations at and within the
+ given location.
+
+ A registration a tuple (location, hib_id).
+ """
+
=== Zope3/lib/python/Zope/App/OFS/Services/ObjectHub/ObjectHub.py 1.2 => 1.3 ===
--- Zope3/lib/python/Zope/App/OFS/Services/ObjectHub/ObjectHub.py:1.2 Mon Nov 11 03:35:28 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ObjectHub/ObjectHub.py Tue Nov 26 14:02:49 2002
@@ -38,8 +38,8 @@
from Zope.ContextWrapper import ContextMethod
from Zope.Proxy.ContextWrapper import isWrapper
from Zope.App.Traversing.ITraverser import ITraverser
-from Zope.App.Traversing import getPhysicalPathString
-from Zope.App.Traversing import locationAsUnicode
+from Zope.App.Traversing import getPhysicalPath
+from Zope.App.Traversing import locationAsTuple, locationAsUnicode
from Zope.Proxy.ProxyIntrospection import removeAllProxies
from Zope.Proxy.ContextWrapper import ContextWrapper
from Zope.ComponentArchitecture import getAdapter
@@ -67,7 +67,9 @@
def __init__(self):
ProtoServiceEventChannel.__init__(self)
+ # int --> tuple of unicodes
self.__hubid_to_location = IOBTree()
+ # tuple of unicodes --> int
self.__location_to_hubid = OIBTree()
# XXX this is copied because of some context method problems
@@ -92,17 +94,17 @@
# generate NotificationHubEvents only if object is known
# ie registered
if IObjectMovedEvent.isImplementedBy(event):
- canonical_location = locationAsUnicode(event.fromLocation)
- hubid = clean_self._lookupHubId(canonical_location)
+ canonical_location = locationAsTuple(event.fromLocation)
+ hubid = clean_self.__location_to_hubid.get(canonical_location)
if hubid is not None:
- canonical_new_location = locationAsUnicode(
+ canonical_new_location = locationAsTuple(
event.location)
location_to_hubid = clean_self.__location_to_hubid
if location_to_hubid.has_key(canonical_new_location):
raise ObjectHubError(
'Cannot move to location %s, '
'as there is already something there'
- % canonical_new_location)
+ % locationAsUnicode(canonical_new_location))
hubid = location_to_hubid[canonical_location]
del location_to_hubid[canonical_location]
location_to_hubid[canonical_new_location] = hubid
@@ -117,8 +119,8 @@
event.object)
clean_self._notify(wrapped_self, event)
else:
- canonical_location = locationAsUnicode(event.location)
- hubid = clean_self._lookupHubId(canonical_location)
+ canonical_location = locationAsTuple(event.location)
+ hubid = clean_self.__location_to_hubid.get(canonical_location)
if hubid is not None:
if IObjectModifiedEvent.isImplementedBy(event):
# send out IObjectModifiedHubEvent to plugins
@@ -138,14 +140,15 @@
canonical_location,
event.object)
clean_self._notify(wrapped_self, event)
-
notify = ContextMethod(notify)
def getHubId(self, location):
'''See interface ILocalObjectHub'''
if isWrapper(location):
- location = getPhysicalPathString(location)
- hubid = self._lookupHubId(location)
+ location = getPhysicalPath(location)
+ else:
+ location = locationAsTuple(location)
+ hubid = self.__location_to_hubid.get(location)
if hubid is None:
raise NotFoundError(locationAsUnicode(location))
else:
@@ -170,17 +173,25 @@
clean_self = removeAllProxies(wrapped_self)
if isWrapper(location):
obj = location
- location = getPhysicalPathString(location)
+ location = getPhysicalPath(location)
else:
obj = None
- canonical_location = locationAsUnicode(location)
- if not location.startswith(u'/'):
+ canonical_location = locationAsTuple(location)
+ if not canonical_location[0] == u'':
raise ValueError("Location must be absolute")
+
+ # This is here to make sure the 'registrations' method won't
+ # trip up on using unichar ffff as a sentinel.
+ for segment in canonical_location:
+ if segment.startswith(u'\uffff'):
+ raise ValueError(
+ "Location contains a segment starting with \\uffff")
+
location_to_hubid = clean_self.__location_to_hubid
if location_to_hubid.has_key(canonical_location):
raise ObjectHubError(
'location %s already in object hub' %
- canonical_location)
+ locationAsUnicode(canonical_location))
hubid = clean_self._generateHubId(canonical_location)
location_to_hubid[canonical_location] = hubid
@@ -198,18 +209,18 @@
'''See interface ILocalObjectHub'''
clean_self = removeAllProxies(wrapped_self)
if isWrapper(location):
- location = getPhysicalPathString(location)
+ location = getPhysicalPath(location)
elif isinstance(location, int):
canonical_location = clean_self.getLocation(location)
else:
- canonical_location = locationAsUnicode(location)
+ canonical_location = locationAsTuple(location)
location_to_hubid = clean_self.__location_to_hubid
hubid_to_location = clean_self.__hubid_to_location
try:
hubid = location_to_hubid[canonical_location]
except KeyError:
raise NotFoundError('location %s is not in object hub' %
- canonical_location)
+ locationAsUnicode(canonical_location))
else:
del hubid_to_location[hubid]
del location_to_hubid[canonical_location]
@@ -221,7 +232,31 @@
canonical_location)
clean_self._notify(wrapped_self, event)
unregister = ContextMethod(unregister)
-
+
+ def numRegistrations(self):
+ """See interface IObjectHub"""
+ # The hubid<-->location mappings should be the same size.
+ # The IOBTree of hubid-->location might be faster to find the
+ # size of, as the keys are ints. But, I haven't tested that.
+ # assert len(self.__hubid_to_location)==len(self.__location_to_hubid)
+ return len(self.__hubid_to_location)
+
+ def registrations(self, location=(u'',)):
+ """See interface IObjectHub"""
+ # Location can be an ascii string a unicode or a tuple of strings
+ # or unicodes. So, get a canonical location first of all.
+ location = locationAsTuple(location)
+ if location == (u'',):
+ # Optimisation when we're asked for all the registered objects.
+ # Returns an IOBTreeItems object.
+ return self.__location_to_hubid.items()
+
+ # BTrees only support searches including the min and max.
+ # So, I need to add to the end of the location a string that will
+ # be larger than any other. I could also use a type that
+ # sorts after unicodes.
+ return self.__location_to_hubid.items(location, location+(u'\uffff',))
+
############################################################
def _generateHubId(self, location):
@@ -234,6 +269,3 @@
self._v_nextid = index + 1
return index
- def _lookupHubId(self, location):
- canonical_location = locationAsUnicode(location)
- return self.__location_to_hubid.get(canonical_location, None)