[Zope3-checkins] CVS: Zope3/src/zope/app/services - module.py:1.12
Jim Fulton
jim@zope.com
Mon, 30 Jun 2003 12:25:53 -0400
Update of /cvs-repository/Zope3/src/zope/app/services
In directory cvs.zope.org:/tmp/cvs-serv18732/src/zope/app/services
Modified Files:
module.py
Log Message:
Changed the implementation strategy and interfaces to not use zodb
module managers.
=== Zope3/src/zope/app/services/module.py 1.11 => 1.12 ===
--- Zope3/src/zope/app/services/module.py:1.11 Thu Jun 26 15:11:49 2003
+++ Zope3/src/zope/app/services/module.py Mon Jun 30 12:25:22 2003
@@ -17,101 +17,69 @@
"""
from persistence import Persistent
-from zodb.code.module import PersistentModuleManager
-from zodb.code.interfaces import IPersistentModuleManager
+from zodb.code.module import PersistentModule, compileModule
from zodb.code.interfaces import IPersistentModuleImportRegistry
from zodb.code.interfaces import IPersistentModuleUpdateRegistry
-from zope.component import getServiceManager
-from zope.context import ContextMethod
-
from zope.interface import implements
+from zope.app import zapi
from zope.app.event import function
from zope.app.fssync.classes import ObjectEntryAdapter, AttrMapping
+from zope.app.interfaces.annotation import IAttributeAnnotatable
from zope.app.interfaces.fssync import IObjectFile
from zope.app.interfaces.file import IFileFactory
-from zope.app.interfaces.container import IDeleteNotifiable
-from zope.app.context import ContextWrapper
-
-
-class Registry(Persistent):
-
- # This is a wrapper around the module service, which is actually
- # the service manager. The service manager is found via context,
- # but the PersistentModuleManager doesn't know about context. To
- # make it behave contextually, this Registry class collaborates
- # with the Manager class below to delegate to the registry found
- # via context.
-
- implements(IPersistentModuleImportRegistry,
- IPersistentModuleUpdateRegistry)
-
- def __init__(self):
- self._v_module_service = None
-
- def setModuleService(self, ms):
- # This method is called by methods of Manager below
- self._v_module_service = ms
-
- # The next three methods are called by the persistent module manager
-
- def findModule(self, name):
- return self._v_module_service.findModule(name)
-
- def setModule(self, name, module):
- return self._v_module_service.setModule(name, module)
-
- def delModule(self, name):
- return self._v_module_service.delModule(name)
+from zope.app.interfaces.services.module import IModuleManager
- def __getstate__(self):
- # So pickling this object doesn't include the module service
- return {}
class Manager(Persistent):
- implements(IPersistentModuleManager, IDeleteNotifiable)
+ implements(IModuleManager, IAttributeAnnotatable)
- # The registry for the manager is the ServiceManager.
- # The association between this manager and the registry
- # is static, but the static association can't be stored
- # explicitly in Zope.
-
- # XXX There is no locking, but every call to setModuleService()
- # for a particular instance should have the same manager argument.
-
- # XXX It would be nice if the lookup via getServiceManager()
- # occurred less often. Best would be to do it only when the
- # object is unpickled.
-
- def __init__(self):
- self._registry = Registry()
- self._manager = PersistentModuleManager(self._registry)
-
- def new(self, name, source):
- self._registry.setModuleService(getServiceManager(self))
- self._manager.new(name, source)
-
- def update(self, source):
- self._registry.setModuleService(getServiceManager(self))
- self._manager.update(source)
-
- def remove(self):
- self._registry.setModuleService(getServiceManager(self))
- self._manager.remove()
-
- new = ContextMethod(new)
- update = ContextMethod(update)
- remove = ContextMethod(remove)
-
- name = property(lambda self: self._manager.name)
- source = property(lambda self: self._manager.source)
-
- def beforeDeleteHook(self, obj, container):
- obj.remove()
- beforeDeleteHook = ContextMethod(beforeDeleteHook)
+ zapi.ContextAwareDescriptors()
+ def __init__(self, name, source):
+ self.name = name
+ self._source = None
+ self.source = source
+
+ def __setstate__(self, state):
+ manager = state.get('_manager')
+ if manager is None:
+ return Persistent.__setstate__(self, state)
+
+ # We need to conver an old-style manager
+ self._module = manager._module
+ self.name = manager.name
+ self._source = manager.source
+ self._recompile = False
+
+ def execute(self):
+ try:
+ mod = self._module
+ except AttributeError:
+ mod = self._module = PersistentModule(self.name)
+ folder = zapi.getWrapperContainer(self)
+ compileModule(mod, folder, self.source)
+ self._recompile = False
+
+ def getModule(self):
+ if self._recompile:
+ self.execute()
+ return self._module
+
+ def _get_source(self):
+ return self._source
+ def _set_source(self, source):
+ if self._source != source:
+ self._source = source
+ self._recompile = True
+ source = property(_get_source, _set_source)
+
+
+# Hack to allow unpickling of old Managers to get far enough for __setstate__
+# to do it's magic:
+Registry = Manager
class ModuleAdapter(ObjectEntryAdapter):
@@ -137,13 +105,14 @@
def __call__(self, name, content_type, data):
assert name.endswith(".py")
name = name[:-3]
- m = Manager()
- m = ContextWrapper(m, self.context)
- m.new(name, data)
+ m = Manager(name, data)
+ m = zapi.ContextWrapper(m, self.context)
+ m.execute()
return m
-# Installer function that can be called from ZCML:
+# Installer function that can be called from ZCML.
+# This installs an import hook necessary to support persistent modules.
def installPersistentModuleImporter(event):
from zodb.code.module import PersistentModuleImporter