[Zope-CVS] CVS: Products/Ape/lib/apelib/core - classifiers.py:1.1.8.1 events.py:1.6.2.1 gateways.py:1.7.2.1 interfaces.py:1.9.2.1 io.py:1.6.2.1 exceptions.py:NONE

Shane Hathaway shane at zope.com
Sat Dec 13 12:08:37 EST 2003


Update of /cvs-repository/Products/Ape/lib/apelib/core
In directory cvs.zope.org:/tmp/cvs-serv20826/lib/apelib/core

Modified Files:
      Tag: ape-0_8-branch
	classifiers.py events.py gateways.py interfaces.py io.py 
Removed Files:
      Tag: ape-0_8-branch
	exceptions.py 
Log Message:
Began a simplification effort.

Keychains are now OIDs.  Many interface methods are now attributes.
Instead of a hierarchy of mappers, there is a namespace of mappers.


=== Products/Ape/lib/apelib/core/classifiers.py 1.1 => 1.1.8.1 ===
--- Products/Ape/lib/apelib/core/classifiers.py:1.1	Wed Apr  9 23:09:55 2003
+++ Products/Ape/lib/apelib/core/classifiers.py	Sat Dec 13 12:08:06 2003
@@ -16,40 +16,41 @@
 $Id$
 """
 
-from apelib.core.interfaces import IClassifier
-from apelib.core.exceptions import SerializationError, DeserializationError
+from apelib.core.interfaces import IConfigurableClassifier, IClassifier
+from apelib.core.interfaces import ClassificationError
 
 
 
 class FixedClassifier:
     """Classifies objects based purely on the keychain."""
 
-    __implements__ = IClassifier
+    __implements__ = IConfigurableClassifier
 
     def __init__(self):
-        self._key_to_res = {}
+        self._oid_to_res = {}
         self._default_res = None
 
-    def register(self, key, mapper_name):
-        self._key_to_res[key] = ({}, mapper_name)
-
-    def registerDefault(self, mapper_name):
-        self._default_res = ({}, mapper_name)
+    def register(self, condition, value, mapper_name):
+        if condition == "oid":
+            self._oid_to_res[oid] = ({}, mapper_name)
+        elif condition == "default":
+            self._default_res = ({}, mapper_name)
 
-    def getResult(self, k):
-        res = self._key_to_res.get(k)
+    def getResult(self, oid):
+        res = self._oid_to_res.get(oid)
         if res is None:
             res = self._default_res
             if res is None:
-                raise KeyError("Key %s is not known to fixed classifier %s" %
-                               (repr(k), repr(self)))
+                raise ClassificationError(
+                    "OID %s is not known to fixed classifier %s" %
+                    (repr(oid), repr(self)))
         return res
 
-    def classifyObject(self, value, keychain):
-        return self.getResult(keychain[-1])
+    def classifyObject(self, event):
+        return self.getResult(event.oid)
 
     def classifyState(self, event):
-        return self.getResult(event.getKeychain()[-1])
+        return self.getResult(event.oid)
 
     def store(self, event, classification):
         pass
@@ -60,11 +61,11 @@
 
     __implements__ = IClassifier
 
-    def classifyObject(self, value, keychain):
-        raise SerializationError("Null classifier")
+    def classifyObject(self, event):
+        raise ClassificationError("Null classifier")
 
     def classifyState(self, event):
-        raise DeserializationError("Null classifier")
+        raise ClassificationError("Null classifier")
 
     def store(self, event, classification):
         pass


=== Products/Ape/lib/apelib/core/events.py 1.6 => 1.6.2.1 ===
--- Products/Ape/lib/apelib/core/events.py:1.6	Sat Aug  9 11:16:32 2003
+++ Products/Ape/lib/apelib/core/events.py	Sat Dec 13 12:08:06 2003
@@ -34,60 +34,30 @@
 
     __implements__ = interfaces.IDatabaseInitEvent
 
-    def __init__(self, connections, clearing):
-        self._connections = connections
-        self._clearing = clearing
-
-    def getConnection(self, name):
-        """Returns the named connection."""
-        return self._connections[name]
-
-    def clearing(self):
-        """Returns true if the database is to be cleared."""
-        return self._clearing
+    def __init__(self, connection, connections, clear_all):
+        self.connection = connection
+        self.connections = connections
+        self.clear_all = clear_all
 
 
 class MapperEvent:
 
     __implements__ = interfaces.IMapperEvent
 
-    def __init__(self, mapper, keychain):
-        self._mapper = mapper
-        self._keychain = keychain
-
-    def getMapper(self):
-        """Returns the mapper for the object being (de)serialized."""
-        return self._mapper
-
-    def getKeychain(self):
-        """Returns the keychain of the object being (de)serialized."""
-        return self._keychain
-
-    def getKey(self):
-        """Returns the last element of the keychain."""
-        return self._keychain[-1]
-
-    def makeKeychain(self, name, stored):
-        kcg = self.getMapper().getKeychainGenerator()
-        return kcg.makeKeychain(self, name, stored)
+    def __init__(self, mapper, oid):
+        self.mapper = mapper
+        self.oid = oid
 
 
 class GatewayEvent (MapperEvent):
 
     __implements__ = interfaces.IGatewayEvent
 
-    def __init__(self, mapper, keychain, connections, classification):
-        MapperEvent.__init__(self, mapper, keychain)
-        self._connections = connections
-        self._classification = classification
-
-    def getConnection(self, name):
-        """Returns the named connection."""
-        return self._connections[name]
-
-    def getClassification(self):
-        """Returns the innermost classification or None."""
-        return self._classification
+    def __init__(self, mapper, oid, connection, connections, classification):
+        MapperEvent.__init__(self, mapper, oid)
+        self.connection = connection
+        self.connections = connections
+        self.classification = classification
 
 
 class LoadEvent (GatewayEvent):
@@ -106,79 +76,40 @@
 
     __implements__ = interfaces.ISDEvent
 
-    _serializer_name = ''
-
-    def __init__(self, keyed_ob_sys, object_mapper, keychain, object):
-        MapperEvent.__init__(self, object_mapper, keychain)
-        self._keyed_ob_sys = keyed_ob_sys
-        self._object = object
-        self._unmanaged = []
-        # _refs is the list of externally referenced objects.
-        # It has the form [(keychain, value)]
-        self._refs = []
-
-    def getKeyedObjectSystem(self):
-        """Returns the IKeyedObjectSystem that generated this event.
-
-        It is needed for loading and identifying other objects.
-        """
-        return self._keyed_ob_sys
-
-    def setSerializerName(self, name):
-        """Sets the name of the next serializer."""
-        assert ':' not in name
-        self._serializer_name = name
-
-    def getSerializerName(self):
-        """Returns the name of the serializer in use."""
-        return self._serializer_name
-
-    def getObject(self):
-        """Returns the object being serialized."""
-        return self._object
-
-    def addUnmanagedPersistentObjects(self, obs):
-        """Notifies that there are unmanaged persistent objects in the object.
-        """
-        self._unmanaged.extend(obs)
-
-    def getUnmanagedPersistentObjects(self):
-        """Returns the list of unmanaged persistent objects."""
-        return self._unmanaged
-
-    def getExternalRefs(self):
-        """Returns the list of external references"""
-        return self._refs
+    def __init__(self, obj_db, mapper, oid, obj):
+        MapperEvent.__init__(self, mapper, oid)
+        self.obj_db = obj_db
+        self.obj = obj
+        self.serializer_name = ''
+        self.upos = []
+        # self.external has the form [(oid, subobject)]
+        self.external = []
 
 
 class DeserializationEvent (SDEvent):
 
     __implements__ = interfaces.IFullDeserializationEvent
 
-    def __init__(self, keyed_ob_sys, object_mapper, keychain, object):
-        SDEvent.__init__(
-            self, keyed_ob_sys, object_mapper, keychain, object)
+    def __init__(self, obj_db, mapper, oid, obj):
+        SDEvent.__init__(self, obj_db, mapper, oid, obj)
         self._loaded_refs = {}  # { (serializer_name, name) -> object }
 
     # IDeserializationEvent interface methods:
 
-    def notifyDeserialized(self, name, value):
-        """See the IDeserializationEvent interface."""
-        assert self._serializer_name is not None
-        self._loaded_refs['%s:%s' % (self._serializer_name, name)] = value
+    def deserialized(self, name, value):
+        self._loaded_refs['%s:%s' % (self.serializer_name, name)] = value
 
-    def dereference(self, name, keychain, hints=None):
+    def load(self, name, oid, hints=None):
         """Retrieves a referenced subobject (usually ghosted initially).
         """
-        kos = self.getKeyedObjectSystem()
-        ob = kos.getObject(keychain, hints)
-        self._refs.append((keychain, ob))
-        self.notifyDeserialized(name, ob)
+        ob = self.obj_db.getObject(oid, hints)
+        self.external.append((oid, ob))
+        self.deserialized(name, ob)
         return ob
 
     # IFullDeserializationEvent interface methods:
 
-    def loadInternalRef(self, ref):
+    def loadRef(self, ref):
         """Returns an object already deserialized by another serializer.
 
         'ref' is a tuple containing (serializer_name, name).
@@ -190,9 +121,8 @@
 
     __implements__ = interfaces.IFullSerializationEvent
 
-    def __init__(self, keyed_ob_sys, object_mapper, keychain, object):
-        SDEvent.__init__(
-            self, keyed_ob_sys, object_mapper, keychain, object)
+    def __init__(self, obj_db, mapper, oid, obj):
+        SDEvent.__init__(self, obj_db, mapper, oid, obj)
         self._attrs = {}
         # _internal_refs:
         # id(ob) -> (serializer_name, name)
@@ -203,9 +133,8 @@
 
     # ISerializationEvent interface methods:
 
-    def notifySerialized(self, name, value, is_attribute):
+    def serialized(self, name, value, is_attribute):
         """See the ISerializationEvent interface."""
-        assert self._serializer_name is not None
         for ob in SIMPLE_IMMUTABLE_OBJECTS:
             # If value is a simple immutable object, don't make a
             # reference to it.  Compare by identity rather than
@@ -219,29 +148,23 @@
                 self._internal_ref_list.append(value)
                 if name is not None:
                     self._internal_refs[idx] = (
-                        '%s:%s' % (self._serializer_name, name))
+                        '%s:%s' % (self.serializer_name, name))
                 else:
                     self._internal_refs[idx] = None
         if is_attribute and name is not None:
             self._attrs[name] = 1
 
-    def identifyObject(self, value):
-        kos = self.getKeyedObjectSystem()
-        return kos.identifyObject(value)
-
-    def notifySerializedRef(self, name, value, is_attribute, keychain):
-        assert keychain is not None
-        self._refs.append((keychain, value))
-        self.notifySerialized(name, value, is_attribute)
-
-    def ignoreAttribute(self, name):
-        """See the ISerializationEvent interface."""
-        self._attrs[name] = 1
-
-    def ignoreAttributes(self, names):
-        """See the ISerializationEvent interface."""
-        for name in names:
-            self._attrs[name] = 1
+    def store(self, name, value, is_attribute, oid):
+        assert oid is not None
+        self.external.append((oid, value))
+        self.serialized(name, value, is_attribute)
+
+    def ignore(self, name_or_names):
+        if isinstance(name_or_names, (str, unicode)):
+            self._attrs[name_or_names] = 1
+        else:
+            for name in names:
+                self._attrs[name] = 1
 
 
     # IFullSerializationEvent interface methods:
@@ -250,8 +173,6 @@
         """Returns the name of all attributes serialized."""
         return self._attrs.keys()
 
-    def getInternalRef(self, ob):
+    def identifyRef(self, ob):
         """Returns (serializer_name, name) or None."""
         return self._internal_refs.get(id(ob))
-
-


=== Products/Ape/lib/apelib/core/gateways.py 1.7 => 1.7.2.1 ===
--- Products/Ape/lib/apelib/core/gateways.py:1.7	Wed Jul 30 17:32:59 2003
+++ Products/Ape/lib/apelib/core/gateways.py	Sat Dec 13 12:08:06 2003
@@ -31,30 +31,28 @@
         self._gws = {}
         if base is not None:
             self._gws.update(base._gws)
+        self._updateSchema()
+
+    def _updateSchema(self):
+        self.schema = {}
+        for name, gw in self._gws.items():
+            s = gw.schema
+            if s is not None:
+                self.schema[name] = s
 
     def addGateway(self, name, gw, force=0):
         if not force and self._gws.has_key(name):
             raise KeyError, "Gateway name %s in use" % name
         self._gws[name] = gw
+        self._updateSchema()
 
     def removeGateway(self, name):
         del self._gws[name]  # raise KeyError if not in use
+        self._updateSchema()
 
     def hasGateway(self, name):
         return self._gws.has_key(name)
 
-    def getSchema(self):
-        """Returns the ISchema of data stored by this gateway.
-
-        See interfaces.ISchema.
-        """
-        res = {}
-        for name, gw in self._gws.items():
-            s = gw.getSchema()
-            if s is not None:
-                res[name] = s
-        return res
-
     def load(self, event):
         """Loads data.
 
@@ -91,12 +89,12 @@
         serials.sort()
         return tuple(serials)
 
-    def getSources(self, event):
+    def getPollSources(self, event):
         """Returns data source information.  See IGateway.
         """
         res = {}
         for gw in self._gws.values():
-            sources = gw.getSources(event)
+            sources = gw.getPollSources(event)
             if sources is not None:
                 res.update(sources)
         return res
@@ -112,22 +110,18 @@
         self.schema = schema
         self.data = {}
 
-    def getSchema(self):
-        return self.schema
-
     def load(self, event):
         # Returns (data, serial)
-        keychain = event.getKeychain()
         try:
-            return self.data[keychain]
+            return self.data[event.oid]
         except KeyError:
-            raise exceptions.NoStateFoundError(keychain)
+            raise exceptions.NoStateFoundError(event.oid)
 
     def store(self, event, data):
         h = time.time()
-        self.data[event.getKeychain()] = (data, h)
+        self.data[event.oid] = (data, h)
         return h
 
-    def getSources(self, event):
+    def getPollSources(self, event):
         return None
 


=== Products/Ape/lib/apelib/core/interfaces.py 1.9 => 1.9.2.1 ===
--- Products/Ape/lib/apelib/core/interfaces.py:1.9	Sat Aug  9 11:16:32 2003
+++ Products/Ape/lib/apelib/core/interfaces.py	Sat Dec 13 12:08:06 2003
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Public interfaces
+"""Public interfaces and exception classes.
 
 $Id$
 """
@@ -19,26 +19,29 @@
 from Interface import Interface, Attribute
 
 
-class ISchema(Interface):
-    """Data schema"""
+class MappingError(Exception):
+    """Object mapping exception"""
 
-    def __eq__(other):
-        """Checks equality with another schema.
+class SerializationError(MappingError):
+    """Error during serialization"""
 
-        This is the only method common to all schema objects.  The
-        idea is that serializers and data gateways need only agree on
-        schemas, and this method allows you to check compatibility.
-        """
+class DeserializationError(MappingError):
+    """Error during deserialization"""
 
+class StoreError(MappingError):
+    """Error while storing"""
 
-class IRelationalSchema(ISchema):
-    """Schema oriented for relational storage.
+class LoadError(MappingError):
+    """Error while loading"""
 
-    Designed to assist integration with relational databases."""
+class ClassificationError(MappingError):
+    """Error during classification"""
 
-    def getColumnDefs():
-        """Returns a sequence of (column_name, column_type, unique_flag)"""
+class NoStateFoundError(MappingError):
+    """No state is there to load"""
 
+class ConfigurationError(Exception):
+    """Invalid mapper configuration"""
 
 
 class IClassFactory(Interface):
@@ -52,14 +55,14 @@
         """
 
 
-class IKeyedObjectSystem (IClassFactory):
-    """A collection of objects identifiable by keychain.
+class IObjectDatabase (IClassFactory):
+    """A collection of objects identifiable by OID.
 
     In apelib.zodb3, the ZODB Connection object (the _p_jar) is
-    an IKeyedObjectSystem.
+    an IObjectDatabase.
     """
 
-    def getObject(keychain, hints=None):
+    def getObject(oid, hints=None):
         """Returns a class instance, possibly ghosted.
 
         Used during deserialization (loading/import).
@@ -70,28 +73,22 @@
         Some hints may be:
 
         classification
-        mapper_name (the mapper name for the last item in the keychain)
-        mapper_names (a list of all mapper names)
+        mapper_name
         """
 
-    def identifyObject(obj):
-        """Returns the keychain of an object.
+    def identify(obj):
+        """Returns the OID of an object.
 
         Used during serialization (storing/export).
-        Returns None if the object is not in the keyed object system.
+        Returns None if the object is not in the object database.
         """
 
-    def newKey():
-        """Returns a new, unique key (which might be used in a keychain).
+    def new_oid():
+        """Returns a new OID.
 
         Used during serialization (storing/export).
         """
 
-    # Deprecated
-    def loadStub(keychain, hints=None):
-        """Deprecated alias for getObject()."""
-
-
 
 
 class IDatabaseInitializer (Interface):
@@ -107,50 +104,34 @@
 class IDatabaseInitEvent (Interface):
     """Interface for events involved in initializing databases."""
 
-    def getConnection(name):
-        """Returns the named connection."""
+    connection = Attribute(description="The current database connection")
 
-    def clearing():
-        """Returns true if the database is to be cleared.
+    clear_all = Attribute(
+        description="""True if the database is to be cleared.
 
-        This method is designed for testing purposes.
-        """
+        This attribute is designed for testing purposes.
+        """)
 
 
 class IMapperEvent (Interface):
     """The base interface for events occurring in context of a mapper."""
 
-    def getMapper():
-        """Returns the mapper for the object being (de)serialized."""
-
-    def getKeychain():
-        """Returns the keychain of the object being (de)serialized."""
+    mapper = Attribute(description="The mapper")
 
-    def getKey():
-        """Returns the last element of the keychain.
-
-        For most purposes, the key can be used as an OID.
-        """
-
-    def makeKeychain(name, stored):
-        """Generates a keychain for a subobject.
-        """
+    oid = Attribute(description="The OID of the object being mapped")
 
 
 class IGatewayEvent (IMapperEvent):
     """Interface for events used by gateways."""
 
-    def getConnection(name):
-        """Returns the named connection."""
+# TODO: figure out how to set the connection attribute even when
+# multiple connections exist.  Resume work in io.py.
 
-    def getClassification():
-        """Returns the innermost classification (for reading only) or None.
+    connection = Attribute(description="The current database connection")
 
-        The innermost classification is the classification of the last
-        key in the keychain.  During traversal of the first element of
-        a keychain, no classification has been determined yet, so this
-        method returns None.
-        """
+    connections = Attribute(description="A mapping of database connections")
+
+    classification = Attribute(description="The classification of the object.")
 
 
 class ILoadEvent (IGatewayEvent):
@@ -164,38 +145,26 @@
 class ISDEvent (IMapperEvent):
     """Base for serialization and deserialization events."""
 
-    def getKeyedObjectSystem():
-        """Returns the IKeyedObjectSystem involved in the event."""
+    obj_db = Attribute(description="The relevant object database")
 
-    def getObject():
-        """Returns the object being (de)serialized."""
+    obj = Attribute(description="The object being (de)serialized.")
 
-    def setSerializerName(name):
-        """Sets the name of the next serializer to be used."""
+    serializer_name = Attribute(description="The serializer in use.")
 
-    def getSerializerName():
-        """Returns the name of the serializer in use."""
+    upos = Attribute(
+        description="""The list of unmanaged persistent objects.
 
-    def addUnmanagedPersistentObjects(obs):
-        """Notifies that there are unmanaged persistent objects in the object.
+        If no attention is paid to unmanaged persistent objects (UPOs),
+        they will not notify ZODB when they are changed, and hence can be
+        a challenge for the application programmer.  Add UPOs to this list
+        so that ZODB will see changes made to them and save the
+        corresponding managed persistent object.""")
+    
+    external = Attribute(
+        description="""The list of external oids.
 
-        If no attention is paid to unmanaged persistent objects
-        (UPOs), they will not notify ZODB when they are changed, and
-        hence can be a challenge for the application programmer.  Use
-        this method to tell ZODB about the UPOs so that ZODB will see
-        changes made to them and save the corresponding managed
-        persistent object.
-        """
-
-    def getUnmanagedPersistentObjects():
-        """Returns the list of unmanaged persistent objects."""
-
-    def getExternalRefs():
-        """Returns the list of external references.
-
-        The list is built up during (de)serialization.
-        The returned list is of the form [(keychain, subobject)].
-        """
+        The list is built up during (de)serialization.  It contains
+        [(oid, subobject)].""")
 
 
 class IDeserializationEvent(ISDEvent):
@@ -206,11 +175,11 @@
     references.
     """
 
-    def notifyDeserialized(name, value):
-        """Indicates that a named internal subobject was deserialized.
+    def deserialized(name, value):
+        """Indicates that a named subobject was deserialized.
         """
 
-    def dereference(name, keychain, mapper_names=None):
+    def load(name, oid, hints=None):
         """Retrieves a referenced subobject (usually ghosted initially).
         """
 
@@ -219,7 +188,7 @@
     """Deserialization event with features for deserializing remainder data.
     """
 
-    def loadInternalRef(ref):
+    def loadRef(ref):
         """Returns an object already deserialized by another serializer.
 
         'ref' is a tuple containing (serializer_name, name).
@@ -234,31 +203,20 @@
     references.
     """
 
-    def notifySerialized(name, value, is_attribute):
-        """Indicates that a named internal subobject was serialized.
+    def serialized(name, value, is_attribute):
+        """Indicates that a named subobject was serialized.
 
         This allows a 'remainder pickler' to refer to subobjects by name.
         Be careful to unwrap acquisition and/or context wrappers around
-        subob before calling this method.
+        the value before calling this method.
         """
 
-    def identifyObject(value):
-        """Returns the keychain of an existing object.
-
-        Returns None if the object is not yet known.
+    def store(name, value, is_attribute, oid):
+        """Notifies the system that a subobject needs to be stored.
         """
 
-    def notifySerializedRef(name, value, is_attribute, keychain):
-        """Indicates that a reference to an external subobject was serialized.
-
-        TODO: write more here. ;-)
-        """
-
-    def ignoreAttribute(name):
-        """Indicates that an attribute should be ignored when storing."""
-
-    def ignoreAttributes(names):
-        """Indicates that several attributes should be ignored."""
+    def ignore(name_or_names):
+        """Indicates that attributes should be ignored when storing."""
 
 
 class IFullSerializationEvent(ISerializationEvent):
@@ -270,29 +228,27 @@
     def getSerializedAttributeNames():
         """Returns the name of all attributes serialized."""
 
-    def getInternalRef(ob):
+    def identifyRef(ob):
         """Returns (serializer_name, name) or None."""
 
 
 class ISerializer(Interface):
     """Object serializer / deserializer"""
 
-    def getSchema():
-        """Returns the schema of records (de)serialized by this component.
-        """
+    schema = Attribute(description="The schema used by this component.")
 
     def canSerialize(obj):
         """Returns true if this serializer can serialize the given object.
         """
 
-    def serialize(obj, event):
+    def serialize(event):
         """Returns the state of this part of the object.
 
         Use the ISerializationEvent to set up internal and external
         references.
         """
 
-    def deserialize(obj, event, state):
+    def deserialize(event, state):
         """Fills in the state of this part of the object.
 
         Use the IDeserializationEvent to resolve external references.
@@ -328,7 +284,7 @@
 
 
 class IGateway (Interface):
-    """Loads and stores data by keychain.
+    """Loads and stores data by OID.
 
     Implementations can store in entire tables, pieces of tables, translate
     for storage in joined tables, or store in some entirely different way.
@@ -337,11 +293,7 @@
     by Martin Fowler.
     """
 
-    def getSchema():
-        """Returns the ISchema of data stored by this gateway.
-
-        See serial.interfaces.ISchema.
-        """
+    schema = Attribute(description="The schema used by this component.")
 
     def load(event):
         """Loads data.
@@ -362,18 +314,19 @@
         Returns a new hash value.
         """
 
-    def getSources(event):
-        """Returns source information for a keychain.
+    def getPollSources(event):
+        """Returns source information for an OID.  event is an IGatewayEvent.
 
         The source information allows the system to poll for changes
         to keep caches in sync with the data.  Where polling is not
         necessary, gateways are free to return None.
 
         The source information is a dictionary in the format:
-        {(repository, source): state}.  The repository must be an
+        {(source_repository, path): state}.  The repository must be an
         ISourceRepository.  The source and state must be in a form
-        recognized by the repository.  Both the repository and source
-        must be hashable.
+        recognized by the repository.  Since they are used as
+        dictionary keys, both the repositories and paths must be
+        hashable.
         """
 
 
@@ -391,14 +344,18 @@
     The keys in classifications are implementation-dependent.
     """
 
-    def classifyObject(value, keychain):
+    def classifyObject(event):
         """Returns a classification and mapper_name.
+
+        event is an ISerializationEvent without a mapper (since this
+        method chooses the mapper).
         """
 
     def classifyState(event):
         """Returns a classification and mapper_name.
 
-        event is an ILoadEvent.
+        event is an ILoadEvent without a mapper (since this method
+        chooses the mapper).
 
         May load the classification from storage.
         """
@@ -422,33 +379,34 @@
 
         'class'     - matches a fully-qualified class name
         'extension' - matches a filename extension
-        'key'       - matched the end of the keychain
-        'fallback'  - matches when no other condition is met.  The
-                      fallback values depend on the classifier.
+        'generic'  - matches when no other condition is met.  The
+                      generic types depend on the classifier, but
+                      usually include 'file', 'directory', 'fileish_object',
+                      and 'folderish_object'.
         """
 
 
-class IKeychainGenerator (Interface):
-    """A utility for generating keychains.
+class IOIDGenerator (Interface):
+    """A utility for generating OIDs.
 
     Many serializers encode references to other objects, but it is
-    desirable to not hard code the format of keychains into
+    desirable to not hard code the format of OIDs into
     ISerializer implementations.  This utility, normally accessed
-    through an IMapperEvent, allows keychain knowledge to be kept in
+    through an IMapperEvent, allows OID knowledge to be kept in
     one place.
     """
 
-    def makeKeychain(event, name, stored):
-        """Returns a new keychain.
+    def new_oid(event, name, stored):
+        """Returns a new oid.
 
         event is an IMapperEvent.  Additionally, it is always either
         an ISDEvent or an IGatewayEvent.
 
         name is the name of the subobject.
 
-        stored is a flag indicating whether the returned keychain will
-        be stored.  If it will not be stored, the generated keychain
-        can not be a random label.
+        stored is a boolean indicating whether the returned oid will be
+        stored.  If it will not be stored, the generated oid can not
+        be arbitrary.
         """
 
 
@@ -456,71 +414,27 @@
     """A hub for mapping a certain kind of object.
     """
 
-    def getSerializer():
-        """Returns the IObjectSerializer for this mapper."""
+    serializer = Attribute(description="The IObjectSerializer for this mapper")
 
-    def getGateway():
-        """Returns the IGateway for this mapper."""
+    gateway = Attribute(description="The IGateway for this mapper")
 
-    def getClassifier():
-        """Returns the IClassifier for objects referenced by this mapper.
+    classifier = Attribute(
+        description="""The IClassifier for this mapper.
 
-        If this mapper references no other objects, it's safe to
-        return None.
-        """
+        If this mapper references no other OIDs, this may be None.""")
 
-    def getSubMapper(name):
-        """Returns the named sub-IMapper.
+    oid_gen = Attribute(
+        description="""The IOIDGenerator for this mapper.
 
-        The name of a sub-mapper is chosen by either a classifier or
-        a serializer.
-        """
+        If this mapper references no other OIDs, this may be None.""")
 
-    def listSubMapperNames():
-        """Returns the name of all sub-IMappers."""
-
-    def getKeychainGenerator():
-        """Returns the IKeychainGenerator for subobjects.
-
-        Some serializers and gateways make use of this.  If no serializer
-        or gateway needs this, it's safe to return None.
-        """
-
-    def getInitializers():
-        """Returns the list of configured IDatabaseInitializers."""
+    initializers = Attribute(description="A list of IDatabaseInitializers.")
 
 
 class IConfigurableMapper (IMapper):
     """Adds operations to IMapper for configuration.
     """
 
-    def setSerializer(s):
-        """Sets the IFullObjectSerializer for this mapper."""
-
-    def setGateway(g):
-        """Returns the IGateway for this mapper."""
-
-    def setClassifier(c):
-        """Sets the IClassifier for this mapper."""
-
-    def setKeychainGenerator(k):
-        """Sets the IKeychainGenerator for subobjects."""
-
-    def addSubMapper(name, m=None, replace=0):
-        """Adds a named sub-IMapper, returning the mapper added.
-
-        If m is None, a default IConfigurableMapper
-        implementation is created.  If replace is not set,
-        the implemenation prevents overriding an existing mapper.
-        """
-
-    def addInitializer(obj):
-        """Adds a database initializer.
-
-        Database initializers get notified of new connections,
-        allowing them to prepare the database.
-        """
-
     def checkConfiguration(path='root', recursive=1):
         """Verifies the mapper configuration is sane.
 
@@ -564,7 +478,7 @@
     Designed to helps keep a cache in sync with its sources.
     """
 
-    def freshen(sources):
+    def poll(sources):
         """Returns changed source information.
 
         The source information is a mapping that maps
@@ -574,4 +488,3 @@
         mapping containing only the items of the input dictionary
         whose state has changed.
         """
-


=== Products/Ape/lib/apelib/core/io.py 1.6 => 1.6.2.1 ===
--- Products/Ape/lib/apelib/core/io.py:1.6	Sat Aug  9 11:16:32 2003
+++ Products/Ape/lib/apelib/core/io.py	Sat Dec 13 12:08:06 2003
@@ -23,23 +23,23 @@
 from events \
      import DatabaseInitEvent, GatewayEvent, LoadEvent, StoreEvent, \
      SerializationEvent, DeserializationEvent
-from interfaces import ITPCConnection, IKeyedObjectSystem
+from interfaces import ITPCConnection, IObjectDatabase
 
 
 class ClassifiedState:
     """Object state with classification information."""
 
-    def __init__(self, state, classification, mapper_names):
+    def __init__(self, state, classification, mapper_name):
         self.state = state
         self.classification = classification
-        self.mapper_names = mapper_names
+        self.mapper_name = mapper_name
 
 
 class GatewayIO:
     """Gateway operations facade."""
 
-    def __init__(self, root_mapper, connections):
-        self._root_mapper = root_mapper
+    def __init__(self, mappers, connections):
+        self._mappers = mappers
         self._conn_map = connections
         # Sort the connections by sort key.  Use an extra index to avoid
         # using connections as sort keys.
@@ -83,11 +83,13 @@
         """
         # Find all initializers, eliminating duplicates.
         initializers = {}  # obj -> 1
+        for mapper in self._mappers.values():
+            for obj in mapper.getInitializers():
+                initializers[obj] = 1
+            
         todo = [self._root_mapper]
         while todo:
             mapper = todo.pop()
-            for obj in mapper.getInitializers():
-                initializers[obj] = 1
             sub = mapper.listSubMapperNames()
             if sub:
                 for name in sub:
@@ -219,7 +221,7 @@
     """Simple import/export facade.
     """
 
-    __implements__ = IKeyedObjectSystem
+    __implements__ = IObjectDatabase
 
     def __init__(self, root_mapper, connections, class_factory=None):
         self._objects = {}     # { keychain -> obj }

=== Removed File Products/Ape/lib/apelib/core/exceptions.py ===




More information about the Zope-CVS mailing list