[Zope-CVS] CVS: Products/AdaptableStorage/serial - ObjectMapper.py:1.4

Shane Hathaway shane@zope.com
Mon, 23 Dec 2002 23:30:03 -0500


Update of /cvs-repository/Products/AdaptableStorage/serial
In directory cvs.zope.org:/tmp/cvs-serv30532/serial

Modified Files:
	ObjectMapper.py 
Log Message:
Provided a way to configure ObjectMappers, with the intent of making
AdaptableStorage easier to explain.  Added IConfigurableObjectMapper
and converted all the mapper setup code to use it.  Included a
checkConfiguration() method which validates the entire object mapper
tree.  Then converted the DBTab-based configuration to use a mapper
factory, which can point to any mapper factory function installed
anywhere.  Tangents to this:

- Refactored Zope2FS and Zope2SQL to use the same code for setting up
mappers, leaving "holes" for the gateways.

- Added connect() and close() methods to ITPCConnection (which doesn't
technically exist yet since I need to choose a name for it. ;-) )

- Factored out common parts of the SQL gateways.

- Implemented the newKey() method of IKeyedObjectSystem, which will
help ZEO environments, in theory.



=== Products/AdaptableStorage/serial/ObjectMapper.py 1.3 => 1.4 ===
--- Products/AdaptableStorage/serial/ObjectMapper.py:1.3	Mon Dec  9 13:25:27 2002
+++ Products/AdaptableStorage/serial/ObjectMapper.py	Mon Dec 23 23:29:33 2002
@@ -16,17 +16,22 @@
 $Id$
 """
 
-from interfaces.public import IObjectMapper
+from interfaces.public \
+     import IConfigurableObjectMapper, IObjectMapper, IObjectSerializer, \
+     IGateway, IClassifier, IKeychainGenerator
 
 
 class ObjectMapper:
 
-    __implements__ = IObjectMapper
+    __implements__ = IConfigurableObjectMapper
 
-    def __init__(self, parent, serializer, gateway,
-                 classifier=None, kgen=None, volatile=None):
-        assert serializer.getSchema() == gateway.getSchema(), (
-            serializer.getSchema(), gateway.getSchema())
+    def __init__(self,
+                 parent=None,
+                 serializer=None,
+                 gateway=None,
+                 classifier=None,
+                 kgen=None,
+                 volatile=None):
         self._sub_mappers = {}
         self._parent = parent
         self._serializer = serializer
@@ -35,8 +40,70 @@
         self._kgen = kgen
         self._volatile = volatile
 
-    def addSubMapper(self, name, m):
+    # IConfigurableObjectMapper implementation
+
+    def setSerializer(self, s):
+        self._serializer = s
+
+    def setGateway(self, g):
+        self._gateway = g
+
+    def setClassifier(self, c):
+        self._classifier = c
+
+    def setKeychainGenerator(self, k):
+        self._kgen = k
+
+    def setVolatile(self, v):
+        self._volatile = v
+
+    def addSubMapper(self, name, m=None, replace=0):
+        if not replace and self._sub_mappers.has_key(name):
+            raise KeyError('mapper name %s already in use' % name)
+        if m is None:
+            m = ObjectMapper(self)
         self._sub_mappers[name] = m
+        return m
+
+    def checkConfiguration(self, names=(), recursive=1):
+        s = self._serializer
+        if s is None:
+            raise RuntimeError(
+                'No serializer configured for mapper %s' % repr(names))
+        if not IObjectSerializer.isImplementedBy(s):
+            raise RuntimeError(
+                'Not an IObjectSerializer: %s' % repr(s))
+        g = self._gateway
+        if g is None:
+            raise RuntimeError(
+                'No gateway configured for mapper %s' % repr(names))
+        if not IGateway.isImplementedBy(g):
+            raise RuntimeError(
+                'Not an IGateway: %s' % repr(g))
+        if s.getSchema() != g.getSchema():
+            raise RuntimeError('Mismatched schemas in mapper %s: %s != %s' % (
+                repr(names), s.getSchema(), g.getSchema()))
+        if self._parent is None:
+            if self._classifier is None:
+                raise RuntimeError('No root classifier configured')
+            if not IClassifier.isImplementedBy(self._classifier):
+                raise RuntimeError(
+                    'Not an IClassifier: %s' % repr(self._classifier))
+            if self._kgen is None:
+                raise RuntimeError('No root keychain generator configured')
+            if not IKeychainGenerator.isImplementedBy(self._kgen):
+                raise RuntimeError(
+                    'Not an IKeychainGenerator: %s' % repr(self._kgen))
+        else:
+            if not IObjectMapper.isImplementedBy(self._parent):
+                raise RuntimeError(
+                    'Not an IObjectMapper: %s' % repr(self._parent))
+
+        if recursive:
+            for name, m in self._sub_mappers.items():
+                m.checkConfiguration((names + (name,)), recursive)
+
+    # IObjectMapper implementation
 
     def getSerializer(self):
         return self._serializer
@@ -67,3 +134,4 @@
         if self._parent is not None:
             return self._parent.isVolatile()
         return None
+