[Zope-CVS] CVS: Products/Ape/lib/apelib/zope2 - apeconf.xml:1.2 mapper.py:1.2 classifier.py:1.3 fsmapper.py:1.3 ofsserial.py:1.3 sqlmapper.py:1.6 basemapper.py:NONE

Shane Hathaway shane@zope.com
Wed, 9 Jul 2003 11:40:23 -0400


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

Modified Files:
	classifier.py fsmapper.py ofsserial.py sqlmapper.py 
Added Files:
	apeconf.xml mapper.py 
Removed Files:
	basemapper.py 
Log Message:
Merged ape-newconf-branch.  Mappers are now configured using XML.


=== Products/Ape/lib/apelib/zope2/apeconf.xml 1.1 => 1.2 ===
--- /dev/null	Wed Jul  9 11:40:20 2003
+++ Products/Ape/lib/apelib/zope2/apeconf.xml	Wed Jul  9 11:40:15 2003
@@ -0,0 +1,205 @@
+<?xml version="1.0"?>
+
+<!-- Basic Zope 2 configuration for Ape. -->
+
+<configuration>
+
+<!-- Root mapper -->
+
+<mapper name="root" class="Persistence.PersistentMapping">
+ <serializer name="root_items"
+   factory="apelib.zodb3.serializers.BasicPersistentMapping" />
+ <serializer name="roll_call" factory="apelib.zodb3.serializers.RollCall" />
+ <variation name="filesystem">
+  <classifier factory="apelib.zope2.classifier.Classifier">
+   <gateway factory="apelib.fs.classification.FSClassificationSection" />
+  </classifier>
+  <keygen factory="apelib.core.keygen.PathKeychainGenerator" />
+  <gateway name="root_items" factory="apelib.zope2.ofsserial.ReadOnlyRoot"
+    param="/" />
+ </variation>
+ <variation name="sql">
+  <classifier factory="apelib.zope2.classifier.Classifier">
+   <gateway factory="apelib.sql.classification.SQLClassification" />
+  </classifier>
+  <keygen factory="apelib.sql.keygen.SQLKeychainGenerator" />
+  <gateway name="root_items" factory="apelib.zope2.ofsserial.ReadOnlyRoot"
+    param="0" />
+ </variation>
+</mapper>
+
+<!-- Abstract mappers -->
+
+<mapper name="base" class="none">
+ <serializer name="id" order="a"
+   factory="apelib.zope2.ofsserial.IdAttribute" />
+ <serializer name="modtime"
+   factory="apelib.zodb3.serializers.ModTimeAttribute" />
+ <serializer name="security"
+   factory="apelib.zope2.security.SecurityAttributes" />
+ <serializer name="remainder" order="z"
+   factory="apelib.zodb3.serializers.RemainingState" />
+ <variation name="filesystem">
+  <gateway name="id" factory="apelib.fs.structure.FSAutoId" />
+  <gateway name="modtime" factory="apelib.fs.structure.FSModTime" />
+  <gateway name="remainder" factory="apelib.fs.properties.FSSectionData"
+    param="remainder" />
+  <gateway name="security" factory="apelib.fs.security.FSSecurityAttributes" />
+ </variation>
+ <variation name="sql">
+  <gateway name="id" use="sql_id" />
+  <gateway name="modtime" use="sql_modtime" />
+  <gateway name="remainder" use="sql_remainder" />
+  <gateway name="security" use="sql_security" />
+ </variation>
+</mapper>
+
+<mapper name="base_p" class="none" extends="base">
+ <serializer name="properties"
+   factory="apelib.zope2.ofsserial.OFSProperties" />
+ <variation name="filesystem">
+  <gateway name="properties" factory="apelib.fs.properties.FSProperties" />
+ </variation>
+ <variation name="sql">
+  <gateway name="properties" use="sql_properties" />
+ </variation>
+</mapper>
+
+<!-- Reusable serializers and gateways -->
+
+<serializer name="folder_items" factory="apelib.zope2.ofsserial.FolderItems" />
+
+<serializer name="optional_properties"
+  factory="apelib.zope2.ofsserial.OptionalOFSProperties" />
+
+<variation name="filesystem">
+ <gateway name="binary_data" factory="apelib.fs.structure.FSFileData"
+   param="binary" />
+ <gateway name="text_data" factory="apelib.fs.structure.FSFileData"
+   param="text" />
+ <gateway name="dir_items" factory="apelib.fs.structure.FSDirectoryItems" />
+</variation>
+
+<variation name="sql">
+ <gateway name="binary_data" factory="apelib.sql.structure.SQLObjectData" />
+ <gateway name="text_data" use="binary_data" />
+ <gateway name="dir_items" factory="apelib.sql.structure.SQLFolderItems" />
+ <gateway name="sql_id" factory="apelib.sql.structure.SQLItemId" />
+ <gateway name="sql_remainder" factory="apelib.sql.structure.SQLRemainder" />
+ <gateway name="sql_modtime" factory="apelib.sql.structure.SQLModTime" />
+ <gateway name="sql_properties" factory="apelib.sql.properties.SQLProperties"/>
+ <gateway name="sql_security"
+   factory="apelib.sql.security.SQLSecurityAttributes" />
+ <gateway name="sql_userlist" factory="apelib.sql.security.SQLUserList" />
+</variation>
+
+<!-- Mappers for particular content types -->
+
+<mapper name="OFS.Folder.Folder" extends="base_p" parent="root">
+ <serializer name="items" use="folder_items" />
+ <gateway name="items" use="dir_items" />
+ <use-for fallback="directory" />
+</mapper>
+
+<mapper name="OFS.Image.File" extends="base_p" parent="root">
+ <serializer name="data" factory="apelib.zope2.ofsserial.FilePData" />
+ <gateway name="data" use="binary_data" />
+ <use-for fallback="file" />
+ <option name="content_type_attr" value="content_type" />
+</mapper>
+
+<mapper name="OFS.Image.Image" extends="OFS.Image.File" parent="root">
+ <use-for extensions=".gif .jpg .jpeg .png" />
+ <option name="content_type_attr" value="content_type" />
+</mapper>
+
+<mapper name="Products.PageTemplates.ZopePageTemplate.ZopePageTemplate"
+  extends="base_p" parent="root">
+ <serializer name="text" factory="apelib.core.serializers.StringDataAttribute"
+  param="_text" />
+ <gateway name="text" use="text_data" />
+ <use-for extensions=".html .htm .zpt .pt" />
+</mapper>
+
+<mapper name="OFS.DTMLMethod.DTMLMethod" extends="base" parent="root">
+ <serializer name="text" factory="apelib.core.serializers.StringDataAttribute"
+  param="raw" />
+ <gateway name="text" use="text_data" />
+ <use-for extensions=".dtml" />
+</mapper>
+
+<mapper name="OFS.DTMLMethod.DTMLDocument"
+  extends="OFS.DTMLMethod.DTMLMethod" parent="root">
+ <serializer name="properties" enabled="false" />
+</mapper>
+
+<mapper name="Products.ZSQLMethods.SQL.SQL" extends="base" parent="root">
+ <serializer name="properties"
+   factory="apelib.zope2.scripts.ZSQLMethodPropertiesSerializer" />
+ <serializer name="text"
+   factory="apelib.zope2.scripts.ZSQLMethodSerializer" />
+ <gateway name="text" use="text_data" />
+ <use-for extensions=".sql" />
+ <variation name="filesystem">
+  <gateway name="properties" factory="apelib.fs.properties.FSProperties"
+    param="ZSQL Properties" />
+ </variation>
+ <variation name="sql">
+  <gateway name="properties" use="sql_properties" />
+ </variation>
+</mapper>
+
+<mapper name="Products.PythonScripts.PythonScript.PythonScript"
+  extends="base" parent="root">
+ <serializer name="body"
+   factory="apelib.zope2.scripts.PythonScriptSerializer" />
+ <gateway name="body" use="text_data" />
+ <use-for extensions=".py" />
+</mapper>
+
+<mapper name="AccessControl.User.UserFolder" extends="base" parent="root">
+ <serializer name="data"
+   factory="apelib.zope2.security.UserFolderSerializer" />
+ <variation name="filesystem">
+  <gateway name="data" factory="apelib.fs.security.FSUserList" />
+ </variation>
+ <variation name="sql">
+  <gateway name="data" use="sql_userlist" />
+ </variation>
+</mapper>
+
+<mapper name="anyfolder" class="any" extends="base_p" parent="root">
+ <serializer name="properties" use="optional_properties" />
+ <serializer name="items" use="folder_items" />
+ <gateway name="items" use="dir_items" />
+ <use-for fallback="folderish_object" />
+</mapper>
+
+<mapper name="anyfile" class="any" extends="base_p" parent="root">
+ <serializer name="properties" use="optional_properties" />
+ <gateway name="remainder" use="binary_data" />
+ <use-for fallback="fileish_object" />
+</mapper>
+
+<mapper name="OFS.Application.Application" extends="base_p" parent="root">
+ <serializer name="items" use="folder_items" />
+ <serializer name="id" enabled="false" />
+ <gateway name="id" enabled="false" />
+ <gateway name="items" use="dir_items" />
+ <variation name="filesystem">
+  <use-for key="/" />
+ </variation>
+ <variation name="sql">
+  <use-for key="0" />
+ </variation>
+</mapper>
+
+<mapper name="anyfile">
+ <!-- Workaround for objects that don't work with the anyfolder mapper,
+      but do fine with anyfile.  -->
+ <use-for class="Products.CMFCore.SkinsTool.SkinsTool" />
+ <use-for class="App.ApplicationManager.ApplicationManager" />
+</mapper>
+
+</configuration>
+


=== Products/Ape/lib/apelib/zope2/mapper.py 1.1 => 1.2 ===
--- /dev/null	Wed Jul  9 11:40:21 2003
+++ Products/Ape/lib/apelib/zope2/mapper.py	Wed Jul  9 11:40:15 2003
@@ -0,0 +1,74 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Zope 2 mapper creation
+
+$Id$
+"""
+
+import os
+import Products
+from apelib.config.apeconf import wireMapper
+
+
+def createMapper(vname, search_products=0):
+    """Builds a mapper from apeconf.xml files.
+    """
+    here = os.path.dirname(__file__)
+    filenames = [os.path.join(here, 'apeconf.xml')]
+    if search_products:
+        seen = {}  # Product name -> 1
+        for path in Products.__path__:
+            for name in os.listdir(path):
+                if not seen.has_key(name):
+                    seen[name] = 1
+                    fn = os.path.join(path, name, 'apeconf.xml')
+                    if os.path.exists(fn):
+                        filenames.append(fn)
+    return wireMapper(filenames, vname, 'root')
+
+
+def createFSMapper(basepath, **kw):
+    """Filesystem mapper factory.
+
+    Returns (mapper, { name -> connection })
+
+    Usage in database configuration file:
+    factory=apelib.zope2.mapper.createFSMapper
+    basepath=/var/zope/data
+    """
+    from apelib.fs.connection import FSConnection
+
+    mapper = createMapper('filesystem', search_products=1)
+    conn = FSConnection(basepath, **kw)
+    return mapper, {'fs': conn}
+
+
+def createSQLMapper(module_name, **kw):
+    """SQL mapper factory.
+
+    Returns (mapper, { name -> connection })
+
+    Usage in database configuration file:
+    factory=apelib.zope2.mapper.createSQLMapper
+    module_name=psycopg
+    params=
+    kwparams=
+    table_prefix=zodb
+    """
+    from apelib.sql.dbapi import DBAPIConnector
+
+    mapper = createMapper('sql', search_products=1)
+    conn = DBAPIConnector(module_name, **kw)
+    return mapper, {'db': conn}
+


=== Products/Ape/lib/apelib/zope2/classifier.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/zope2/classifier.py:1.2	Wed Jun  4 11:59:14 2003
+++ Products/Ape/lib/apelib/zope2/classifier.py	Wed Jul  9 11:40:15 2003
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Zope 2 meta_type based classification.
+"""Zope 2 object classification.
 
 $Id$
 """
@@ -24,7 +24,7 @@
 from apelib.core.interfaces import IClassifier
 from apelib.core.exceptions import SerializationError, DeserializationError
 
-# guess_extension() is useful but it's unoptimized and sometimes
+# guess_extension() is useful, but it's unoptimized and sometimes
 # chooses strange extensions.  fixed_extensions does nothing other than
 # suggest a filename extension given a content type.  It contains
 # some better defaults.
@@ -39,110 +39,76 @@
     }
 
 
-class MetaTypeClassifier:
-    """A classifier based on meta_type attributes.
+class Classifier:
+    """A classifier with some minimal Zope 2 extensions.
     """
     __implements__ = IClassifier
 
-    # flag values (constant)
-    CONTENT_TYPE_ATTR = 1
-
 
     def __init__(self, gw=None):
         self.gw = gw
-        self.key_to_res = {}
-        self.ext_to_mt = {}
-        self.mt_to_ext = {}
-        self.fmt_to_mt = {}
-        self.mt_to_mapper = {}
-        self.flags = {}
-
-
-    def setGateway(self, gw):
-        self.gw = gw
-
-
-    def register(self, meta_type, mapper_name, extensions=()):
-        """Registers a mapper to handle a Zope meta_type."""
-        for ext in extensions:
-            if not ext.startswith('.'):
-                ext = '.' + ext
-            ext = ext.lower()
-            self.ext_to_mt[ext] = meta_type
-        if extensions:
-            self.mt_to_ext[meta_type] = extensions[0]
-        self.mt_to_mapper[meta_type] = mapper_name
-
-
-    def registerKey(self, meta_type, mapper_name, key):
-        """Registers a mapper to handle a specific path.
-
-        For example, the application object mapper usually handles
-        the path '/'.
-        """
-        self.key_to_res[key] = ({'meta_type': meta_type}, mapper_name)
-
-
-    def registerDefaultLoader(self, meta_type, mapper_name, isdir):
-        """Registers a mapper to load unknown files or directories."""
-        if isdir:
-            ext = '<directory>'
-        else:
-            ext = '<file>'
-        self.ext_to_mt[ext] = meta_type
-        self.mt_to_mapper[meta_type] = mapper_name
-
-
-    def registerDefaultStorage(self, meta_type, mapper_name, folderish):
-        """Registers a mapper to store unknown objects."""
-        if folderish:
-            fmt = 'folder'
+        self.key_to_mapper = {}
+        self.class_to_mapper = {}
+        self.ext_to_mapper = {}
+        self.fallback_to_mapper = {}
+        self.options = {}  # { (mapper_name, option) -> value }
+
+    def getGateway(self):
+        return self.gw
+
+
+    def register(self, attr, value, mapper_name):
+        if attr == 'key':
+            self.key_to_mapper[value] = mapper_name
+        elif attr == 'extension':
+            self.ext_to_mapper[value] = mapper_name
+        elif attr == 'class':
+            self.class_to_mapper[value] = mapper_name
+        elif attr == 'fallback':
+            assert value in ('directory', 'file',
+                             'folderish_object', 'fileish_object'), value
+            self.fallback_to_mapper[value] = mapper_name
         else:
-            fmt = 'file'
-        self.fmt_to_mt[fmt] = meta_type
-        self.mt_to_mapper[meta_type] = mapper_name
+            raise ValueError('Unknown attr: %s' % attr)
 
 
-    def setFlags(self, mapper_name, flags):
-        """Sets flags associated with a certain mapper."""
-        self.flags[mapper_name] = flags
-
+    def setOption(self, mapper_name, option, value):
+        assert option in ('default_extension', 'content_type_attr'), option
+        self.options[(mapper_name, option)] = value
+            
 
     def classifyObject(self, value, keychain):
         """Chooses a mapper and classification for storing an object."""
-        res = self.key_to_res.get(keychain[-1])
-        if res is not None:
-            return res
-        mt = value.meta_type
-        mapper_name = self.mt_to_mapper.get(mt)
+        mapper_name = self.key_to_mapper.get(keychain[-1])
+        if mapper_name is not None:
+            # Shortcut.
+            return {'mapper_name': mapper_name}, mapper_name
+        klass = value.__class__
+        class_name = '%s.%s' % (klass.__module__, klass.__name__)
+        classification = {'class_name': class_name}
+        mapper_name = self.class_to_mapper.get(class_name)
         if mapper_name is None:
             folderish = isinstance(value, ObjectManager)
-            # Store in a default format
+            # Store in a fallback format
             if folderish:
-                fmt = 'folder'
+                fallback = 'folderish_object'
             else:
-                fmt = 'file'
-            mt = self.fmt_to_mt.get(fmt)
-            if mt is None:
-                raise SerializationError(
-                    'No classification known for %s' % repr(keychain))
-            mapper_name = self.mt_to_mapper.get(mt)
-            if mapper_name is None:
-                raise SerializationError(
-                    'No mapper known for meta_type %s' % repr(mt))
-        klass = value.__class__
-        ci = '%s:%s' % (klass.__module__, klass.__name__)
-        classification = {'meta_type': mt, 'class_name': ci}
-
-        flags = self.flags.get(mapper_name, 0)
-        if flags and (flags & MetaTypeClassifier.CONTENT_TYPE_ATTR):
-            ct = str(getattr(aq_base(value), 'content_type', None))
-            if ct:
-                ext = fixed_extensions.get(ct)
-                if ext is None:
-                    ext = guess_extension(ct)
+                fallback = 'fileish_object'
+            mapper_name = self.fallback_to_mapper.get(fallback)
+            if mapper_name is not None:
+                # Force a particular mapper
+                classification['mapper_name'] = mapper_name
+        if mapper_name is None:
+            raise SerializationError(
+                'No mapper known for class %s' % repr(class_name))
+        cta = self.options.get((mapper_name, 'content_type_attr'))
+        if cta is not None:
+            ct = str(getattr(aq_base(value), cta, None))
+            ext = fixed_extensions.get(ct)
+            if ext is None:
+                ext = guess_extension(ct)
         else:
-            ext = self.mt_to_ext.get(mt)
+            ext = self.options.get((mapper_name, 'default_extension'))
         if ext:
             classification['extension'] = ext
 
@@ -151,35 +117,39 @@
 
     def classifyState(self, event):
         """Chooses a mapper and classification for loading an object."""
-        keychain = event.getKeychain()
-        res = self.key_to_res.get(keychain[-1])
-        if res is not None:
-            return res
+        mapper_name = self.key_to_mapper.get(event.getKey())
+        if mapper_name is not None:
+            # Shortcut.
+            return {'mapper_name': mapper_name}, mapper_name
         classification, serial = self.gw.load(event)
-        mt = classification.get('meta_type')
-        if mt is None:
+        class_name = classification.get('class_name')
+        mapper_name = classification.get('mapper_name')
+        if mapper_name is None:
+            # bw compat: look for certain meta_types.
+            mt = classification.get('meta_type')
+            if mt == '(folderish object)':
+                mapper_name = self.fallback_to_mapper.get('folderish_object')
+            elif mt == '(fileish object)':
+                mapper_name = self.fallback_to_mapper.get('fileish_object')
+        if mapper_name is None and class_name is not None:
+            mapper_name = self.class_to_mapper.get(class_name)
+        if mapper_name is None:
             t = classification.get('node_type')
             if t == 'd':
                 # Directory
-                mt = self.ext_to_mt.get('<directory>', 'Folder')
+                mapper_name = self.fallback_to_mapper.get('directory')
             elif t == 'f':
                 # File
                 ext = classification.get('extension')
                 if ext:
                     if not ext.startswith('.'):
                         ext = '.' + ext
-                    mt = self.ext_to_mt.get(ext.lower())
-                if not mt:
-                    mt = self.ext_to_mt.get('<file>', 'File')
-            else:
-                raise DeserializationError(
-                    'No classification known for %s' % repr(keychain))
-            assert mt is not None
-            classification['meta_type'] = mt
-        mapper_name = self.mt_to_mapper.get(mt)
+                    mapper_name = self.ext_to_mapper.get(ext.lower())
+                if not mapper_name:
+                    mapper_name = self.fallback_to_mapper.get('file')
         if mapper_name is None:
             raise DeserializationError(
-                'No mapper known for meta_type %s' % repr(mt))
+                'No mapper known for class %s' % repr(class_name))
         return classification, mapper_name
 
 


=== Products/Ape/lib/apelib/zope2/fsmapper.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/zope2/fsmapper.py:1.2	Tue Apr 29 18:11:52 2003
+++ Products/Ape/lib/apelib/zope2/fsmapper.py	Wed Jul  9 11:40:15 2003
@@ -11,113 +11,12 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""A basic mapping from Zope 2 objects to the filesystem.
+"""Deprecated alias.
 
 $Id$
 """
+from mapper import createFSMapper as createMapper
 
-from apelib.core import gateways, keygen
-from apelib.fs \
-     import classification, connection, properties, security, structure
-from apelib.zope2 import basemapper
-
-
-def createAbstractMapper():
-    """Object mapper factory.
-
-    Usage in database configuration file:
-    factory=apelib.zope2.fsmapper.createMapper
-    """
-    root_mapper = basemapper.createZope2Mapper('/', 0)
-    root_mapper.getClassifier().setGateway(
-        classification.FSClassificationSection())
-    root_mapper.setKeychainGenerator(keygen.PathKeychainGenerator())
-    file_binary_data = structure.FSFileData(text=0)
-    file_text_data = structure.FSFileData(text=1)
-
-    # abstract base gateway
-    g = gateways.CompositeGateway()
-    g.addGateway('id', structure.FSAutoId())
-    g.addGateway('modtime', structure.FSModTime())
-    g.addGateway('remainder', properties.FSSectionData('remainder'))
-    g.addGateway('security', security.FSSecurityAttributes())
-    root_mapper.getSubMapper('base').setGateway(g)
-    base = g
-
-    # abstract base gateway with properties
-    g = gateways.CompositeGateway(base)
-    g.addGateway('properties', properties.FSProperties())
-    root_mapper.getSubMapper('base_p').setGateway(g)
-    base_p = g
-
-    # folder gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('items', structure.FSDirectoryItems())
-    root_mapper.getSubMapper('OFS.Folder.Folder').setGateway(g)
-
-    # page template gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('text', file_text_data)
-    root_mapper.getSubMapper('ZopePageTemplate').setGateway(g)
-
-    # dtml method gateway
-    g = gateways.CompositeGateway(base)
-    g.addGateway('text', file_text_data)
-    root_mapper.getSubMapper('OFS.DTMLMethod.DTMLMethod').setGateway(g)
-    
-    # dtml document gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('text', file_text_data)
-    root_mapper.getSubMapper('OFS.DTMLDocument.DTMLDocument').setGateway(g)
-
-    # zsqlmethod mapper
-    g = gateways.CompositeGateway(base)
-    g.addGateway('text', file_text_data)
-    g.addGateway('properties', properties.FSProperties('ZSQL Properties'), 1)
-    root_mapper.getSubMapper('Products.ZSQLMethods.SQL.SQL').setGateway(g)
-
-    # python script mapper
-    g = gateways.CompositeGateway(base)
-    g.addGateway('body', file_text_data)
-    root_mapper.getSubMapper('PythonScript').setGateway(g)
-
-    # file gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('data', file_binary_data)
-    root_mapper.getSubMapper('OFS.Image.File').setGateway(g)
-
-    # image gateway is identical
-    root_mapper.getSubMapper('OFS.Image.Image').setGateway(g)
-
-    # user folder gateway
-    g = gateways.CompositeGateway(base)
-    g.addGateway('data', security.FSUserList())
-    root_mapper.getSubMapper('AccessControl.User.UserFolder').setGateway(g)
-
-    # anyfolder object gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('items', structure.FSDirectoryItems())
-    root_mapper.getSubMapper('anyfolder').setGateway(g)
-
-    # anyfile object gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('remainder', file_binary_data, 1)
-    root_mapper.getSubMapper('anyfile').setGateway(g)
-
-    # application gateway
-    g = gateways.CompositeGateway(base_p)
-    g.removeGateway('id')
-    g.addGateway('items', structure.FSDirectoryItems())
-    root_mapper.getSubMapper('OFS.Application.Application').setGateway(g)
-
-    root_mapper.checkConfiguration()
-
-    return root_mapper
-
-
-def createMapper(basepath, **kw):
-    """Returns (mapper, { name -> connection })"""
-    mapper = createAbstractMapper()
-    conn = connection.FSConnection(basepath, **kw)
-    return mapper, {'fs': conn}
-
+from zLOG import LOG, WARNING
+LOG('Ape', WARNING, 'apelib.zope2.fsmapper.createMapper is deprecated. '
+    'Please use apelib.zope2.mapper.createFSMapper instead.')


=== Products/Ape/lib/apelib/zope2/ofsserial.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/zope2/ofsserial.py:1.2	Wed Jun 11 09:58:53 2003
+++ Products/Ape/lib/apelib/zope2/ofsserial.py	Wed Jul  9 11:40:15 2003
@@ -28,6 +28,9 @@
 from apelib.core.interfaces import ISerializer
 from apelib.core.schemas import FieldSchema, RowSequenceSchema
 from apelib.core.exceptions import SerializationError
+from apelib.core.serializers import OptionalSerializer
+from apelib.zodb3.gateways import ReadOnlyItems
+
 
 string_repr_types = {
     # Properties that are safe to render as strings for storage.
@@ -77,78 +80,32 @@
 
 
 class FolderItems:
-    """Serializer for the items in an ObjectManager.
-
-    This version does not store keychains, but instead assumes they
-    can be computed."""
-
-    __implements__ = ISerializer
-
-    schema = RowSequenceSchema()
-    schema.addField('id', 'string', 1)
-
-    def getSchema(self):
-        return self.schema
-
-    def canSerialize(self, object):
-        return isinstance(object, ObjectManager)
-
-    def serialize(self, object, event):
-        assert isinstance(object, ObjectManager), repr(object)
-        state = []
-        event.ignoreAttribute('_objects')
-        mps = getattr(object, '_mount_points', None)
-        for id, subob in object.objectItems():
-            if mps and mps.has_key(id):
-                # Store the mount point rather than the mounted object.
-                subob = mps[id]
-            base = aq_base(subob)
-            keychain = event.identifyObject(base)
-            expected = event.makeKeychain(id, 0)
-            if keychain is not None and keychain != expected:
-                raise SerializationError(
-                    "Subobject %s has unexpected keychain, %s. Expected %s." %
-                    (repr(base), repr(keychain), repr(expected)))
-            keychain = expected
-            event.notifySerializedRef(id, base, 1, keychain)
-            state.append((id,))
-        event.ignoreAttribute('_use_fixed_oids_')
-        # Add a marker that tells the folder it has to move/rename
-        # in a special way.  The _setOb patch sees this attribute.
-        object._use_fixed_oids_ = 1
-        return state
-
-    def deserialize(self, object, event, state):
-        assert isinstance(object, ObjectManager)
-        object._use_fixed_oids_ = 1
-        for (id,) in state:
-            keychain = event.makeKeychain(id, 0)
-            subob = event.dereference(id, keychain)
-            setattr(object, id, subob)
-            object._objects += ({'id': id, 'meta_type':
-                                 subob.__class__.meta_type},)
-
-
-class FolderItemsByKeychain:
-    """ """
+    """Zope 2 folder items (de)serializer
+    """
     __implements__ = ISerializer
 
     schema = RowSequenceSchema()
     schema.addField('id', 'string', 1)
     schema.addField('keychain', 'keychain')
 
+    # The fixed_oids flag must be turned on when serializing to
+    # an object system with meaningful OIDs (like the filesystem.)
+    # It doesn't need to be on for object systems with arbitrary
+    # OIDs such as SQL databases.
+    fixed_oids = 1
+
     def getSchema(self):
         return self.schema
 
-    def canSerialize(self, object):
-        return isinstance(object, ObjectManager)
+    def canSerialize(self, obj):
+        return isinstance(obj, ObjectManager)
 
-    def serialize(self, object, event):
-        assert isinstance(object, ObjectManager), repr(object)
+    def serialize(self, obj, event):
+        assert isinstance(obj, ObjectManager), repr(obj)
         state = []
         event.ignoreAttribute('_objects')
-        mps = getattr(object, '_mount_points', None)
-        for id, subob in object.objectItems():
+        mps = getattr(obj, '_mount_points', None)
+        for id, subob in obj.objectItems():
             if mps and mps.has_key(id):
                 # Store the mount point rather than the mounted object.
                 subob = mps[id]
@@ -158,14 +115,21 @@
                 keychain = event.makeKeychain(id, 1)
             event.notifySerializedRef(id, base, 1, keychain)
             state.append((id, keychain))
+        if self.fixed_oids:
+            event.ignoreAttribute('_use_fixed_oids_')
+            # Add a marker that tells the folder it has to move/rename
+            # in a special way.  The _setOb patch sees this attribute.
+            obj._use_fixed_oids_ = 1
         return state
 
-    def deserialize(self, object, event, state):
-        assert isinstance(object, ObjectManager)
+    def deserialize(self, obj, event, state):
+        assert isinstance(obj, ObjectManager)
+        if self.fixed_oids:
+            obj._use_fixed_oids_ = 1
         for (id, keychain) in state:
             subob = event.dereference(id, keychain)
-            setattr(object, id, subob)
-            object._objects += ({'id': id, 'meta_type':
+            setattr(obj, id, subob)
+            obj._objects += ({'id': id, 'meta_type':
                                  subob.__class__.meta_type},)
 
 
@@ -301,4 +265,21 @@
                 # Fall back to a default.
                 data = ''
             object._updateProperty(id, data)
+
+
+class ReadOnlyRoot(ReadOnlyItems):
+    """Zope 2 application root."""
+
+    def __init__(self, root_key):
+        try:
+            root_key = int(root_key)
+        except ValueError:
+            root_key = str(root_key)
+        ReadOnlyItems.__init__(self, {'Application': (root_key,)})
+
+
+class OptionalOFSProperties(OptionalSerializer):
+
+    def __init__(self):
+        OptionalSerializer.__init__(self, OFSProperties(), [])
 


=== Products/Ape/lib/apelib/zope2/sqlmapper.py 1.5 => 1.6 ===
--- Products/Ape/lib/apelib/zope2/sqlmapper.py:1.5	Mon May 19 15:32:36 2003
+++ Products/Ape/lib/apelib/zope2/sqlmapper.py	Wed Jul  9 11:40:15 2003
@@ -11,138 +11,12 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""A basic mapping from Zope 2 objects to a Postgres database.
+"""Deprecated alias.
 
 $Id$
 """
+from mapper import createSQLMapper as createMapper
 
-from apelib.core import gateways
-from apelib.sql import classification, keygen, properties, security, structure
-from apelib.sql import dbapi
-from apelib.zope2 import basemapper
-
-
-def createAbstractMapper():
-    """Object mapper factory, with extra return arg for testing purposes
-    """
-    root_mapper = basemapper.createZope2Mapper(0, 1)
-    root_mapper.setKeychainGenerator(keygen.SQLKeychainGenerator())
-
-    folder_items_gw = structure.SQLFolderItems()
-    item_id_gw = structure.SQLItemId()
-    remainder_gw = structure.SQLRemainder()
-    file_data_gw = structure.SQLObjectData()
-    modtime_gw = structure.SQLModTime()
-    properties_gw = properties.SQLProperties()
-    security_gw = security.SQLSecurityAttributes()
-    userlist_gw = security.SQLUserList()
-    classification_gw = classification.SQLClassification()
-    keychain_gen = keygen.SQLKeychainGenerator()
-
-    for initializer in (
-        folder_items_gw,
-        item_id_gw,
-        remainder_gw,
-        file_data_gw,
-        modtime_gw,
-        properties_gw,
-        security_gw,
-        userlist_gw,
-        classification_gw,
-        keychain_gen):
-        root_mapper.addInitializer(initializer)
-
-    root_mapper.getClassifier().setGateway(classification_gw)
-
-    # abstract base gateway
-    g = gateways.CompositeGateway()
-    g.addGateway('id', item_id_gw)
-    g.addGateway('modtime', modtime_gw)
-    g.addGateway('remainder', remainder_gw)
-    g.addGateway('security', security_gw)
-    root_mapper.getSubMapper('base').setGateway(g)
-    base = g
-
-    # abstract base gateway with properties
-    g = gateways.CompositeGateway(base)
-    g.addGateway('properties', properties_gw)
-    root_mapper.getSubMapper('base_p').setGateway(g)
-    base_p = g
-
-    # folder gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('items', folder_items_gw)
-    root_mapper.getSubMapper('OFS.Folder.Folder').setGateway(g)
-
-    # page template gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('text', file_data_gw)
-    root_mapper.getSubMapper('ZopePageTemplate').setGateway(g)
-
-    # dtml method gateway
-    g = gateways.CompositeGateway(base)
-    g.addGateway('text', file_data_gw)
-    root_mapper.getSubMapper('OFS.DTMLMethod.DTMLMethod').setGateway(g)
-    
-    # dtml document gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('text', file_data_gw)
-    root_mapper.getSubMapper('OFS.DTMLDocument.DTMLDocument').setGateway(g)
-
-    # zsqlmethod mapper
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('text', file_data_gw)
-    root_mapper.getSubMapper('Products.ZSQLMethods.SQL.SQL').setGateway(g)
-
-    # python script mapper
-    g = gateways.CompositeGateway(base)
-    g.addGateway('body', file_data_gw)
-    root_mapper.getSubMapper('PythonScript').setGateway(g)
-
-    # file gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('data', file_data_gw)
-    root_mapper.getSubMapper('OFS.Image.File').setGateway(g)
-
-    # image gateway is identical
-    root_mapper.getSubMapper('OFS.Image.Image').setGateway(g)
-
-    # user folder gateway
-    g = gateways.CompositeGateway(base)
-    g.addGateway('data', userlist_gw)
-    root_mapper.getSubMapper('AccessControl.User.UserFolder').setGateway(g)
-
-    # anyfolder object gateway
-    g = gateways.CompositeGateway(base_p)
-    g.addGateway('items', folder_items_gw)
-    root_mapper.getSubMapper('anyfolder').setGateway(g)
-
-    # anyfile object gateway
-    g = gateways.CompositeGateway(base_p)
-    root_mapper.getSubMapper('anyfile').setGateway(g)
-
-    # application gateway
-    g = gateways.CompositeGateway(base_p)
-    g.removeGateway('id')
-    g.addGateway('items', folder_items_gw)
-    root_mapper.getSubMapper('OFS.Application.Application').setGateway(g)
-
-    root_mapper.checkConfiguration()
-
-    return root_mapper
-
-
-def createMapper(module_name, **kw):
-    """Object mapper factory.
-
-    Usage in database configuration file:
-    factory=apelib.zope2.sqlmapper.createDBAPIMapper
-    module_name=psycopg
-    params=
-    kwparams=
-    table_prefix=zodb
-    """
-    mapper = createAbstractMapper()
-    conn = dbapi.DBAPIConnector(module_name, **kw)
-    return mapper, {'db': conn}
-
+from zLOG import LOG, WARNING
+LOG('Ape', WARNING, 'apelib.zope2.sqlmapper.createMapper is deprecated. '
+    'Please use apelib.zope2.mapper.createSQLMapper instead.')

=== Removed File Products/Ape/lib/apelib/zope2/basemapper.py ===