[Zope-CVS] CVS: Products/Ape/lib/apelib/zope2 - apeconf.xml:1.1.2.1 baseconf.xml:1.1.2.3 classifier.py:1.2.2.1 fsmapper.py:1.2.2.2 ofsserial.py:1.2.2.2
Shane Hathaway
shane@zope.com
Mon, 7 Jul 2003 18:59:39 -0400
Update of /cvs-repository/Products/Ape/lib/apelib/zope2
In directory cvs.zope.org:/tmp/cvs-serv2793/zope2
Modified Files:
Tag: ape-newconf-branch
baseconf.xml classifier.py fsmapper.py ofsserial.py
Added Files:
Tag: ape-newconf-branch
apeconf.xml
Log Message:
Implemented XML-based configuration. The filesystem tests pass.
Used an experimental approach for mixing configuration from multiple sources.
Take a look at zope2/apeconf.xml.
=== Added File Products/Ape/lib/apelib/zope2/apeconf.xml ===
<?xml version="1.0"?>
<configuration>
<!-- Root mapper -->
<mapper name="zope2" class="Persistence.PersistentMapping">
<serializer name="root_items"
factory="apelib.zodb3.serializers.BasicPersistentMapping" />
<serializer name="roll_call" factory="apelib.zodb3.serializers.RollCall" />
<variant name="filesystem">
<classifier factory="apelib.zope2.classifier.MetaTypeClassifier">
<gateway factory="apelib.fs.classification.FSClassificationSection" />
</classifier>
<keygen factory="apelib.core.keygen.PathKeychainGenerator" />
<gateway name="root_items" factory="apelib.zope2.ofsserial.ReadOnlyRoot"
param="/" />
</variant>
</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" />
<variant 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" />
</variant>
</mapper>
<mapper name="base_p" class="none" extends="base">
<serializer name="properties"
factory="apelib.zope2.ofsserial.OFSProperties" />
<variant name="filesystem">
<gateway name="properties" factory="apelib.fs.properties.FSProperties" />
</variant>
</mapper>
<!-- Reusable serializers and gateways -->
<serializer name="folder_items" factory="apelib.zope2.ofsserial.FolderItems" />
<serializer name="optional_properties"
factory="apelib.zope2.ofsserial.OptionalOFSProperties" />
<variant name="filesystem">
<gateway name="fs_binary_data" factory="apelib.fs.structure.FSFileData"
param="binary" />
<gateway name="fs_text_data" factory="apelib.fs.structure.FSFileData"
param="text" />
<gateway name="fs_dir_items" factory="apelib.fs.structure.FSDirectoryItems" />
</variant>
<!-- Mappers for particular content types -->
<mapper name="OFS.Folder.Folder" extends="base_p" parent="zope2">
<serializer name="items" use="folder_items" />
<use-for fallback="directory" />
<variant name="filesystem">
<gateway name="items" use="fs_dir_items" />
</variant>
</mapper>
<mapper name="OFS.Image.File" extends="base_p" parent="zope2">
<serializer name="data" factory="apelib.zope2.ofsserial.FilePData" />
<use-for fallback="file" />
<option name="content_type_attr" value="content_type" />
<variant name="filesystem">
<gateway name="data" use="fs_binary_data" />
</variant>
</mapper>
<mapper name="OFS.Image.Image" extends="OFS.Image.File" parent="zope2">
<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="zope2">
<serializer name="text" factory="apelib.core.serializers.StringDataAttribute"
param="_text" />
<use-for extensions=".html .htm .zpt .pt" />
<variant name="filesystem">
<gateway name="text" use="fs_text_data" />
</variant>
</mapper>
<mapper name="OFS.DTMLMethod.DTMLMethod" extends="base" parent="zope2">
<serializer name="text" factory="apelib.core.serializers.StringDataAttribute"
param="raw" />
<use-for extensions=".dtml" />
<variant name="filesystem">
<gateway name="text" use="fs_text_data" />
</variant>
</mapper>
<mapper name="OFS.DTMLMethod.DTMLDocument"
extends="OFS.DTMLMethod.DTMLMethod" parent="zope2">
<serializer name="properties" enabled="false" />
</mapper>
<mapper name="Products.ZSQLMethods.SQL.SQL" extends="base" parent="zope2">
<serializer name="properties"
factory="apelib.zope2.scripts.ZSQLMethodPropertiesSerializer" />
<serializer name="text"
factory="apelib.zope2.scripts.ZSQLMethodSerializer" />
<use-for extensions=".sql" />
<variant name="filesystem">
<gateway name="properties" factory="apelib.fs.properties.FSProperties"
param="ZSQL Properties" />
<gateway name="text" use="fs_text_data" />
</variant>
</mapper>
<mapper name="Products.PythonScripts.PythonScript.PythonScript"
extends="base" parent="zope2">
<serializer name="body"
factory="apelib.zope2.scripts.PythonScriptSerializer" />
<use-for extensions=".py" />
<variant name="filesystem">
<gateway name="body" use="fs_text_data" />
</variant>
</mapper>
<mapper name="AccessControl.User.UserFolder" extends="base" parent="zope2">
<serializer name="data"
factory="apelib.zope2.security.UserFolderSerializer" />
<variant name="filesystem">
<gateway name="data" factory="apelib.fs.security.FSUserList" />
</variant>
</mapper>
<mapper name="anyfolder" class="any" extends="base_p" parent="zope2">
<serializer name="properties" use="optional_properties" />
<serializer name="items" use="folder_items" />
<use-for fallback="folderish_object" />
<variant name="filesystem">
<gateway name="items" use="fs_dir_items" />
</variant>
</mapper>
<mapper name="anyfile" class="any" extends="base_p" parent="zope2">
<serializer name="properties" use="optional_properties" />
<use-for fallback="fileish_object" />
<variant name="filesystem">
<gateway name="remainder" use="fs_binary_data" />
</variant>
</mapper>
<mapper name="OFS.Application.Application" extends="base_p" parent="zope2">
<serializer name="items" use="folder_items" />
<serializer name="id" enabled="false" />
<gateway name="id" enabled="false" />
<variant name="filesystem">
<gateway name="items" use="fs_dir_items" />
<use-for key="/" />
</variant>
</mapper>
<mapper name="anyfile">
<use-for class="Products.CMFCore.SkinsTool.SkinsTool" />
<use-for class="App.ApplicationManager.ApplicationManager" />
</mapper>
</configuration>
=== Products/Ape/lib/apelib/zope2/baseconf.xml 1.1.2.2 => 1.1.2.3 ===
--- Products/Ape/lib/apelib/zope2/baseconf.xml:1.1.2.2 Thu Jun 26 00:35:08 2003
+++ Products/Ape/lib/apelib/zope2/baseconf.xml Mon Jul 7 18:59:32 2003
@@ -15,11 +15,11 @@
factory="apelib.zodb3.serializers.ModTimeAttribute" />
<serializer name="security"
factory="apelib.zope2.security.SecurityAttributes" />
- <serializer name="remainder" final="true"
+ <serializer name="remainder" order="final"
factory="apelib.zodb3.serializers.RemainingState" />
</mapper>
-<mapper name="base_p" class="none" extends="base" parent="zope2">
+<mapper name="base_p" class="none" extends="base">
<serializer name="properties"
factory="apelib.zope2.ofsserial.OFSProperties" />
</mapper>
=== Products/Ape/lib/apelib/zope2/classifier.py 1.2 => 1.2.2.1 ===
--- Products/Ape/lib/apelib/zope2/classifier.py:1.2 Wed Jun 4 11:59:14 2003
+++ Products/Ape/lib/apelib/zope2/classifier.py Mon Jul 7 18:59:32 2003
@@ -44,105 +44,66 @@
"""
__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>'
+ self.key_to_mapper = {}
+ self.class_to_mapper = {}
+ self.ext_to_mapper = {}
+ self.fallback_to_mapper = {}
+ self.options = {} # { (mapper_name, option) -> value }
+
+
+ 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:
- 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'
- 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)
+ klass = value.__class__
+ class_name = '%s.%s' % (klass.__module__, klass.__name__)
+ classification = {'class_name': class_name}
+ mapper_name = self.key_to_mapper.get(keychain[-1])
+ if mapper_name is None:
+ 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 +112,37 @@
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
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:
+ mapper_name = self.key_to_mapper.get(event.getKey())
+ 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.2.1 => 1.2.2.2 ===
--- Products/Ape/lib/apelib/zope2/fsmapper.py:1.2.2.1 Tue Jun 24 17:38:44 2003
+++ Products/Ape/lib/apelib/zope2/fsmapper.py Mon Jul 7 18:59:32 2003
@@ -23,7 +23,7 @@
from apelib.zodb3.gateways import ReadOnlyItems
-def createAbstractMapper():
+def XXXcreateAbstractMapper():
"""Object mapper factory.
Usage in database configuration file:
@@ -120,6 +120,18 @@
root_mapper.checkConfiguration()
return root_mapper
+
+
+def createAbstractMapper():
+ import os
+ from apelib.config.apeconf import makeComponentSystem
+ here = os.path.dirname(__file__)
+ filenames = (os.path.join(here, 'apeconf.xml'),)
+ vnames = ('filesystem', '')
+ cs = makeComponentSystem(filenames, vnames)
+ m = cs.get('mapper', 'zope2')
+ m.checkConfiguration(path='zope2')
+ return m
def createMapper(basepath, **kw):
=== Products/Ape/lib/apelib/zope2/ofsserial.py 1.2.2.1 => 1.2.2.2 ===
--- Products/Ape/lib/apelib/zope2/ofsserial.py:1.2.2.1 Tue Jun 24 17:38:44 2003
+++ Products/Ape/lib/apelib/zope2/ofsserial.py Mon Jul 7 18:59:32 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.
@@ -262,4 +265,17 @@
# Fall back to a default.
data = ''
object._updateProperty(id, data)
+
+
+class ReadOnlyRoot(ReadOnlyItems):
+ """Zope 2 application root."""
+
+ def __init__(self, root_key):
+ ReadOnlyItems.__init__(self, {'Application': (str(root_key),)})
+
+
+class OptionalOFSProperties(OptionalSerializer):
+
+ def __init__(self):
+ OptionalSerializer.__init__(self, OFSProperties(), [])