[Zope-CVS] CVS: Products/Ape/lib/apelib/config - apeconf.py:1.5
common.py:1.3 minitables.py:NONE
Shane Hathaway
shane at zope.com
Mon Feb 2 10:07:48 EST 2004
Update of /cvs-repository/Products/Ape/lib/apelib/config
In directory cvs.zope.org:/tmp/cvs-serv26672/lib/apelib/config
Modified Files:
apeconf.py common.py
Removed Files:
minitables.py
Log Message:
Moved ape-0_8-branch to the HEAD.
>From CHANGES.txt:
- Major restructuring to reduce the number of concepts in
Ape. Keychains and keys have been replaced with simple string OIDs.
There is now a flat namespace of mappers instead of a tree. Only
one classifier and one OID generator are used in any object
database.
- The ZODB root object is now stored on the filesystem.
=== Products/Ape/lib/apelib/config/apeconf.py 1.4 => 1.5 ===
--- Products/Ape/lib/apelib/config/apeconf.py:1.4 Thu Aug 14 16:17:00 2003
+++ Products/Ape/lib/apelib/config/apeconf.py Mon Feb 2 10:07:17 2004
@@ -17,17 +17,14 @@
"""
from __future__ import nested_scopes
-from apelib.core.mapper import Mapper
+from apelib.core.mapper import Mapper, MapperConfiguration
from apelib.core.serializers import CompositeSerializer, AnyObjectSerializer
from apelib.core.gateways import CompositeGateway
-from apelib.core.interfaces import IDatabaseInitializer
+from apelib.core.interfaces import IDatabaseInitializer, ConfigurationError
-from minitables import Table, TableSchema
+from apelib.zodb3.zodbtables import Table, TableSchema
from common import Directive, DirectiveReader, ComponentSystem
-class AssemblyError(Exception):
- """Error while assembling components"""
-
class MapperDeclaration(Directive):
schema = TableSchema()
@@ -37,14 +34,14 @@
class MapperAttribute(Directive):
schema = TableSchema()
schema.addColumn('mapper_name', primary=1)
- # Attribute names: 'class', 'parent', 'extends'
+ # Attribute names: 'class', 'extends', 'register-class'
schema.addColumn('name', primary=1, indexed=1)
schema.addColumn('value')
class ComponentDefinition(Directive):
schema = TableSchema()
- # comptypes: 'serializer', 'gateway', 'classifier', 'keygen'
+ # comptypes: 'serializer', 'gateway', 'classifier', 'oid_generator'
schema.addColumn('comptype', primary=1)
schema.addColumn('name', primary=1)
schema.addColumn('producer')
@@ -54,20 +51,12 @@
schema = TableSchema()
schema.addColumn('mapper_name', primary=1)
schema.addColumn('comptype', primary=1)
- schema.addColumn('producer')
-
-
-class MapperCompositeComponent(Directive):
- schema = TableSchema()
- schema.addColumn('mapper_name', primary=1)
- schema.addColumn('comptype', primary=1)
schema.addColumn('name', primary=1)
schema.addColumn('producer')
schema.addColumn('order')
-class MapperRegistration(Directive):
- # Contains a use-for directive
+class MapperUseFor(Directive):
schema = TableSchema()
schema.addColumn('mapper_name', primary=1)
schema.addColumn('attr', primary=1)
@@ -164,33 +153,38 @@
mapper_name = str(attrs['name'])
vars['mapper_name'] = mapper_name
d.append(MapperDeclaration(source, mapper_name))
- for key in ('class', 'parent', 'extends'):
+ for key in ('class', 'extends', 'register-class'):
if attrs.has_key(key):
- d.append(MapperAttribute(source, mapper_name, key, attrs[key]))
+ value = attrs[key]
+ if (key == 'register-class'):
+ if value.lower() == 'true':
+ value = True
+ elif value.lower() == 'false':
+ value = False
+ else:
+ raise ValueError("Value must be true or false")
+ d.append(MapperAttribute(source, mapper_name, key, value))
- def handle_component(source, vars, attrs, comptype, multiple):
+ def handle_mapper_component(source, vars, attrs, comptype):
d = vars['directives']
producer = makeProducer(source, comptype, attrs)
mapper_name = vars.get('mapper_name')
if mapper_name is None:
# Reusable component
name = attrs['name']
- directive = ComponentDefinition(source, comptype, name, producer)
- elif multiple:
+ directive = ComponentDefinition(
+ source, comptype, name, producer)
+ else:
# Composite component of a mapper
name = attrs['name']
- directive = MapperCompositeComponent(
+ directive = MapperComponent(
source, mapper_name, comptype,
name, producer, attrs.get('order', 'middle'))
- else:
- # Singular component of a mapper
- directive = MapperComponent(
- source, mapper_name, comptype, producer)
d.append(directive)
return producer
def handle_serializer(source, vars, attrs):
- handle_component(source, vars, attrs, 'serializer', multiple=1)
+ handle_mapper_component(source, vars, attrs, 'serializer')
def handle_gateway(source, vars, attrs):
p = vars.get('classifier_producer')
@@ -206,19 +200,25 @@
source)
p.sub_producer = makeProducer(source, 'gateway', attrs)
else:
- handle_component(source, vars, attrs, 'gateway', multiple=1)
+ handle_mapper_component(source, vars, attrs, 'gateway')
def handle_classifier(source, vars, attrs):
- p = handle_component(source, vars, attrs, 'classifier', multiple=0)
- vars['classifier_producer'] = p
+ d = vars['directives']
+ producer = makeProducer(source, 'classifier', attrs)
+ directive = ComponentDefinition(source, 'classifier', '', producer)
+ d.append(directive)
+ vars['classifier_producer'] = producer
- def handle_keygen(source, vars, attrs):
- handle_component(source, vars, attrs, 'keygen', multiple=0)
+ def handle_oid_generator(source, vars, attrs):
+ d = vars['directives']
+ producer = makeProducer(source, 'oid_generator', attrs)
+ directive = ComponentDefinition(source, 'oid_generator', '', producer)
+ d.append(directive)
def handle_use_for(source, vars, attrs):
d = vars['directives']
mapper_name = vars['mapper_name']
- for attr in ('class', 'extensions', 'fallback', 'key'):
+ for attr in ('class', 'extensions', 'generic', 'oid'):
if attrs.has_key(attr):
v = attrs[attr]
if attr == 'extensions':
@@ -227,7 +227,7 @@
if not ext.startswith('.'):
ext = '.' + ext
ext = ext.lower()
- d.append(MapperRegistration(
+ d.append(MapperUseFor(
source, mapper_name, 'extension', ext))
if first:
# Use a classifier option to set the default
@@ -235,15 +235,8 @@
first = 0
d.append(ClassifierOption(
source, mapper_name, 'default_extension', ext))
- elif attr == 'key':
- try:
- v = int(v)
- except ValueError:
- v = str(v)
- d.append(MapperRegistration(
- source, mapper_name, attr, v))
else:
- d.append(MapperRegistration(
+ d.append(MapperUseFor(
source, mapper_name, attr, v))
def handle_option(source, vars, attrs):
@@ -260,7 +253,7 @@
'serializer': handle_serializer,
'gateway': handle_gateway,
'classifier': handle_classifier,
- 'keygen': handle_keygen,
+ 'oid-generator': handle_oid_generator,
'use-for': handle_use_for,
'option': handle_option,
}
@@ -270,7 +263,7 @@
class BasicComponentAssembler:
- """Assembler for simple components.
+ """Assembler for producer-based components.
Configures at the time of creation.
"""
@@ -280,8 +273,8 @@
records = compsys.dtables.query(
ComponentDefinition, comptype=comptype, name=name)
if not records:
- raise AssemblyError("No %s component named %s exists"
- % (comptype, repr(name)))
+ raise ConfigurationError("No %s component named %s exists"
+ % (comptype, repr(name)))
assert len(records) == 1
producer = records[0]['producer']
self.producer = producer
@@ -294,67 +287,46 @@
class MapperAssembler:
- """Assembler for mapper components.
+ """Assembler for one mapper component.
"""
-
def __init__(self, compsys, comptype, name):
self.compsys = compsys
- self.dtables = dtables = compsys.dtables
+ dtables = compsys.dtables
self.mapper_name = name
if not dtables.query(MapperDeclaration, mapper_name=name):
- raise AssemblyError("No mapper named %s exists" % repr(name))
+ raise ConfigurationError("No mapper named %s exists" % repr(name))
self.subobjs = [] # all subobjects
self.attrs = {}
for record in dtables.query(MapperAttribute, mapper_name=name):
- self.attrs[record['name']] = record['value']
+ self.attrs[record.name] = record.value
self.prepareSubComponents()
def prepareSubComponents(self):
- self.single_comps = {} # comptype -> record
self.multi_comps = {} # comptype -> name -> record
+ dtables = self.compsys.dtables
name = self.mapper_name
all_names = [] # mapper_name and all of its base mapper_names
while name:
all_names.append(name)
- records = self.dtables.query(MapperComponent, mapper_name=name)
- for r in records:
- self.single_comps.setdefault(r['comptype'], r)
- records = self.dtables.query(
- MapperCompositeComponent, mapper_name=name)
+ records = dtables.query(
+ MapperComponent, mapper_name=name)
for r in records:
- d = self.multi_comps.setdefault(r['comptype'], {})
- d.setdefault(r['name'], r)
- name = self.dtables.queryField(
+ d = self.multi_comps.setdefault(r.comptype, {})
+ d.setdefault(r.name, r)
+ name = dtables.queryField(
MapperAttribute, 'value', mapper_name=name, name='extends')
if name and name in all_names:
- raise AssemblyError(
+ raise ConfigurationError(
"Circular extension in mappers %s" % repr(all_names))
- self.sub_mapper_names = []
- records = self.dtables.query(
- MapperAttribute, name='parent', value=self.mapper_name)
- for r in records:
- self.sub_mapper_names.append(r['mapper_name'])
def create(self):
self.obj = Mapper()
return self.obj
def configure(self):
- self.setParent()
self.addSerializers()
self.addGateways()
- self.setClassifier()
- self.setKeygen()
self.addInitializers()
- self.addSubMappers()
- self.registerClassifications()
-
- def setParent(self):
- if self.attrs.get('parent'):
- p = self.compsys.get('mapper', self.attrs['parent'])
- self.obj.setParent(p)
- else:
- self.obj.setParent(None)
def addSerializers(self):
cname = self.attrs.get('class')
@@ -370,115 +342,107 @@
cname = self.mapper_name
pos = cname.rfind('.')
if pos < 0:
- raise AssemblyError("Class name must include a module name")
+ raise ConfigurationError("Class name must include a module name")
s = CompositeSerializer(cname[:pos], cname[pos + 1:])
-
+
d = self.multi_comps.get('serializer')
if d:
- ordered = [(r.get('order', '').lower(), name, r)
+ ordered = [((r.order or '').lower(), name, r)
for name, r in d.items()]
ordered.sort()
for order, name, r in ordered:
- o = r['producer'](self.compsys)
+ o = r.producer(self.compsys)
if o is not None:
- s.addSerializer(str(name), o)
+ s.add(str(name), o)
self.subobjs.append(o)
- self.obj.setSerializer(s)
+ self.obj.serializer = s
def addGateways(self):
g = CompositeGateway()
d = self.multi_comps.get('gateway')
if d:
for name, r in d.items():
- o = r['producer'](self.compsys)
+ o = r.producer(self.compsys)
if o is not None:
- g.addGateway(str(name), o)
+ g.add(str(name), o)
self.subobjs.append(o)
- self.obj.setGateway(g)
-
- def setClassifier(self):
- r = self.single_comps.get('classifier')
- if r:
- o = r['producer'](self.compsys)
- self.classifier = o
- if o is not None:
- self.obj.setClassifier(o)
- self.subobjs.append(o)
- gw = o.getGateway()
- if gw is not None:
- self.subobjs.append(gw)
-
- def setKeygen(self):
- r = self.single_comps.get('keygen')
- if r:
- o = r['producer'](self.compsys)
- if o is not None:
- self.obj.setKeychainGenerator(o)
- self.subobjs.append(o)
+ self.obj.gateway = g
def addInitializers(self):
for o in self.subobjs:
if IDatabaseInitializer.isImplementedBy(o):
- self.obj.addInitializer(o)
+ self.obj.initializers.append(o)
+
+
+class ClassifierAssembler (BasicComponentAssembler):
+ """Assembler for one classifier.
+ """
+ def __init__(self, compsys, comptype, name):
+ assert comptype == "classifier", comptype
+ assert name == '', name
+ BasicComponentAssembler.__init__(self, compsys, comptype, name)
- def addSubMappers(self):
- for name in self.sub_mapper_names:
- o = self.compsys.get('mapper', name)
- self.obj.addSubMapper(name, o)
+ def create(self):
+ self.obj = BasicComponentAssembler.create(self)
+ return self.obj
- def registerClassifications(self):
- """Registers classifications on behalf of sub-mappers."""
+ def configure(self):
+ dtables = self.compsys.dtables
all_regs = {} # { (attr, value) -> mapper_name }
all_options = {} # { (mapper_name, option) -> value }
- for name in self.sub_mapper_names:
+ mapper_names = [r.mapper_name for r in
+ dtables.query(MapperDeclaration)]
+ # Gather classification options from each mapper configuration.
+ for name in mapper_names:
# use-for directives
- records = self.dtables.query(
- MapperRegistration, mapper_name=name)
+ records = dtables.query(
+ MapperUseFor, mapper_name=name)
for r in records:
- key = ((r['attr'], r['value']))
+ key = ((r.attr, r.value))
if all_regs.has_key(key) and all_regs[key] != name:
- raise AssemblyError(
+ raise ConfigurationError(
"Mappers %s and %s are contending over %s == %s" % (
name, all_regs[key],
- r['attr'], repr(r['value'])))
+ repr(r.attr), repr(r.value)))
all_regs[key] = name
- # class="" attributes
- class_name = self.dtables.queryField(
- MapperAttribute, 'value', mapper_name=name, name='class')
- if class_name is None:
- class_name = name
- elif class_name in ('none', 'any'):
- class_name = None
- if class_name is not None:
- # Add an implicit use-for directive
- key = ('class', class_name)
- if all_regs.has_key(key) and all_regs[key] != name:
- raise AssemblyError(
- "Mappers %s and %s are contending over %s == %s" % (
- name, all_regs[key],
- 'class', repr(class_name)))
- all_regs[key] = name
+ register_class = dtables.queryField(
+ MapperAttribute, 'value', mapper_name=name,
+ name='register-class')
+ if register_class or register_class is None:
+ # Create an implicit 'use-for class' directive
+ class_name = dtables.queryField(
+ MapperAttribute, 'value', mapper_name=name, name='class')
+ if class_name is None:
+ class_name = name
+ elif class_name in ('none', 'any'):
+ class_name = None
+ if class_name is not None:
+ key = ('class', class_name)
+ if all_regs.has_key(key) and all_regs[key] != name:
+ raise ConfigurationError(
+ "Mappers %s and %s are contending over %s == %s" % (
+ name, all_regs[key],
+ "'class'", repr(class_name)))
+ all_regs[key] = name
# options
- records = self.dtables.query(
+ records = dtables.query(
ClassifierOption, mapper_name=name)
for r in records:
- all_options[(name, r['option'])] = r['value']
+ all_options[(name, r.option)] = r.value
+ # Perform the registrations.
if all_regs or all_options:
- if self.classifier is None:
- raise AssemblyError(
- "Mapper %s needs a classifier because it has "
- "sub-mappers with registrations" % self.mapper_name)
for (attr, value), name in all_regs.items():
- self.classifier.register(attr, value, name)
+ self.obj.register(attr, value, name)
for (name, option), value in all_options.items():
- self.classifier.setOption(name, option, value)
-
+ self.obj.setOption(name, option, value)
+
+
-def wireMapper(filenames, vname='', mapper_name='root'):
- """Returns an Ape mapper built according to the configuration files.
+def configure(filenames, vname=''):
+ """Returns a MapperConfiguration built from configuration files.
"""
handlers = getElementHandlers()
reader = DirectiveReader(handlers)
@@ -487,9 +451,19 @@
directives = reader.getDirectives(vname)
cs = ComponentSystem(directives)
cs.addComponentType('mapper', MapperAssembler)
- for comptype in ('serializer', 'gateway', 'classifier', 'keygen'):
+ cs.addComponentType('classifier', ClassifierAssembler)
+ for comptype in ('serializer', 'gateway', 'oid_generator'):
cs.addComponentType(comptype, BasicComponentAssembler)
- mapper = cs.get('mapper', mapper_name)
- mapper.checkConfiguration(path=mapper_name)
- return mapper
+ mappers = {}
+ for record in cs.dtables.query(MapperDeclaration):
+ name = record.mapper_name
+ mappers[name] = cs.get('mapper', name)
+ classifier = cs.get('classifier', '')
+ oid_gen = cs.get('oid_generator', '')
+ conf = MapperConfiguration(mappers, classifier, oid_gen)
+ for obj in (classifier.gateway, oid_gen):
+ if IDatabaseInitializer.isImplementedBy(obj):
+ conf.initializers.append(obj)
+ conf.check()
+ return conf
=== Products/Ape/lib/apelib/config/common.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/config/common.py:1.2 Wed Jul 9 11:39:55 2003
+++ Products/Ape/lib/apelib/config/common.py Mon Feb 2 10:07:17 2004
@@ -19,7 +19,7 @@
import xml.sax.handler
from xml.sax import parse
-import minitables
+from apelib.zodb3 import zodbtables
class Directive:
@@ -41,8 +41,9 @@
kw[key] = args[n]
self.data = kw
unique_key = [self.__class__]
- for name in self.schema.getPrimaryNames():
- unique_key.append(kw[name])
+ for column in self.schema.columns:
+ if column.primary:
+ unique_key.append(kw[column.name])
self.unique_key = tuple(unique_key)
def getUniqueKey(self):
@@ -51,7 +52,7 @@
def index(self, tables):
t = tables.get(self.__class__)
if t is None:
- t = minitables.Table(self.schema)
+ t = zodbtables.Table(self.schema)
tables[self.__class__] = t
t.insert(self.data)
=== Removed File Products/Ape/lib/apelib/config/minitables.py ===
More information about the Zope-CVS
mailing list