[Zope3-checkins] CVS: Zope3/src/zope/app/services - configuration.py:1.37
Guido van Rossum
guido@python.org
Wed, 18 Jun 2003 16:12:41 -0400
Update of /cvs-repository/Zope3/src/zope/app/services
In directory cvs.zope.org:/tmp/cvs-serv21151/services
Modified Files:
configuration.py
Log Message:
A major change in the semantics of the ConfigurationRegistry class
(and its interface). When you deactivate an entry, the next entry is
activated. A None entry may occur (once) at any position. The info()
method now has an optional keep_dummy argument, which, when True,
returns an info entry corresponding to the dummy None in the data.
This is done so that uninstalling a bundle has a more natural effect:
all the activations that were overridden by the bundle are reactivated
when the bundle is uninstalled.
It is possible that this breaks part of the UI; I've fixed the only
place in the UI that I'm aware of that uses this, the code for
activating services; but there may be other places.
=== Zope3/src/zope/app/services/configuration.py 1.36 => 1.37 ===
--- Zope3/src/zope/app/services/configuration.py:1.36 Thu Jun 12 15:28:08 2003
+++ Zope3/src/zope/app/services/configuration.py Wed Jun 18 16:12:11 2003
@@ -123,6 +123,18 @@
class ConfigurationRegistry(Persistent):
+ """Configuration registry implementation.
+
+ The invariants for _data are as follows:
+
+ (1) The last element (if any) is not None
+
+ (2) No value occurs more than once
+
+ (3) Each value except None is a relative path from the nearest
+ service manager to an object implementing IConfiguration
+ """
+
implements(IConfigurationRegistry)
_data = ()
@@ -169,20 +181,24 @@
data = wrapped_self._data
if data:
if data[0] == cid:
- # It's active, we need to switch in None
- data = (None, ) + data[1:]
-
- # we need to notify it that it's inactive.
+ # Tell it that it is no longer active
configuration.deactivated()
- else:
- data = tuple([item for item in data if item != cid])
+ # Remove it from our data
+ data = tuple([item for item in data if item != cid])
- # Check for empty registry
- if len(data) == 1 and data[0] is None:
- data = ()
+ # Check for trailing None
+ if data and data[-1] is None:
+ data = data[:-1]
- wrapped_self._data = data
+ if data and data[0] is not None:
+ # Activate the newly active component
+ sm = getServiceManager(wrapped_self)
+ new = traverse(sm, data[0])
+ new.activated()
+
+ # Write data back
+ wrapped_self._data = data
unregister = ContextMethod(unregister)
def registered(wrapped_self, configuration):
@@ -191,29 +207,39 @@
registered = ContextMethod(registered)
def activate(wrapped_self, configuration):
- cid = wrapped_self._id(configuration)
+ if configuration is None:
+ cid = None
+ else:
+ cid = wrapped_self._id(configuration)
data = wrapped_self._data
- if cid in data:
+ if cid is None and not data:
+ return # already in the state we want
+
+ if cid is None or cid in data:
if data[0] == cid:
return # already active
- if data[0] is None:
- # Remove leading None marker
- data = data[1:]
- else:
- # We need to deactivate the currently active component
+ if data[0] is not None:
+ # Deactivate the currently active component
sm = getServiceManager(wrapped_self)
old = traverse(sm, data[0])
old.deactivated()
+ # Insert it in front, removing it from back
+ data = (cid, ) + tuple([item for item in data if item != cid])
- wrapped_self._data = (cid, ) + tuple(
- [item for item in data if item != cid]
- )
-
- configuration.activated()
+ # Check for trailing None
+ if data[-1] == None:
+ data = data[:-1]
+
+ # Write data back
+ wrapped_self._data = data
+
+ if configuration is not None:
+ # Tell it that it is now active
+ configuration.activated()
else:
raise ValueError(
@@ -223,21 +249,34 @@
def deactivate(wrapped_self, configuration):
cid = wrapped_self._id(configuration)
+ data = wrapped_self._data
- if cid in wrapped_self._data:
+ if cid not in data:
+ raise ValueError(
+ "Configuration to be deactivated is not registered",
+ configuration)
- if wrapped_self._data[0] != cid:
- return # already inactive
+ if data[0] != cid:
+ return # already inactive
- # Just stick None on the front
- wrapped_self._data = (None, ) + wrapped_self._data
+ # Tell it that it is no longer active
+ configuration.deactivated()
- configuration.deactivated()
+ if None not in data:
+ # Append None
+ data += (None,)
+
+ # Move it to the end
+ data = data[1:] + data[:1]
+
+ if data[0] is not None:
+ # Activate the newly active component
+ sm = getServiceManager(wrapped_self)
+ new = traverse(sm, data[0])
+ new.activated()
- else:
- raise ValueError(
- "Configuration to be deactivated is not registered",
- configuration)
+ # Write data back
+ wrapped_self._data = data
deactivate = ContextMethod(deactivate)
def active(wrapped_self):
@@ -255,21 +294,22 @@
def __nonzero__(self):
return bool(self._data)
- def info(wrapped_self):
+ def info(wrapped_self, keep_dummy=False):
sm = getServiceManager(wrapped_self)
- result = [{'id': path,
+ data = wrapped_self._data
+ if not data and keep_dummy:
+ data += (None,)
+
+ result = [{'id': path or "",
'active': False,
'configuration': (path and traverse(sm, path))
- }
- for path in wrapped_self._data
- ]
-
- if result:
- if result[0]['configuration'] is None:
- del result[0]
- else:
- result[0]['active'] = True
+ }
+ for path in data if path or keep_dummy
+ ]
+
+ if keep_dummy or (result and result[0]['configuration'] is not None):
+ result[0]['active'] = True
return result
info = ContextMethod(info)