extending composer and organize.schema to provide basis for tumsm

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1845 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-07-29 13:28:50 +00:00
parent 7aad7a6430
commit 242c4a4921
13 changed files with 225 additions and 31 deletions

View file

@ -54,7 +54,9 @@ class Template(object):
implements(ITemplate) implements(ITemplate)
componentStorage = Jeep componentStorage = Jeep
components = None
def __init__(self): def __init__(self):
self.components = self.componentStorage() if self.componentStorage is not None:
self.components = self.componentStorage()

View file

@ -31,25 +31,25 @@ class Instance(object):
implements(IInstance) implements(IInstance)
templateStorage = dict templateFactory = dict
templateAttributeName = '__ctc_templates__' templateAttributeName = '__ctc_template__'
aspect = 'composer.default' aspect = 'composer.default'
def __init__(self, context): def __init__(self, context):
self.context = context self.context = context
self.instances = []
def setTemplate(self, template): def setTemplate(self, temp):
templates = getattr(self.context, template = getattr(self.context,
self.templateAttributeName, self.templateStorage()) self.templateAttributeName,
templates.setdefault(self.aspect, template) self.templateFactory())
setattr(self.context, self.templateAttributeName, templates) template.setdefault(self.aspect, temp)
setattr(self.context, self.templateAttributeName, template)
def getTemplate(self): def getTemplate(self):
templates = getattr(self.context, self.templateAttributeName, {}) template = getattr(self.context, self.templateAttributeName, {})
return templates.get(self.aspect, None) return template.get(self.aspect, [])
template = property(getTemplate, setTemplate) template = property(getTemplate, setTemplate)
def applyTemplate(self, *args, **kw): def applyTemplates(self, *args, **kw):
raise ValueError('To be implemented by subclass') raise ValueError('To be implemented by subclass')

View file

@ -52,7 +52,7 @@ class ITemplate(Interface):
""" """
components = Attribute('An ordered sequence of the components this ' components = Attribute('An ordered sequence of the components this '
'object is built upon') 'object is built upon')
# instances # instances
@ -62,9 +62,9 @@ class IInstance(Interface):
""" """
context = Attribute('Object this instance adapter has been created for') context = Attribute('Object this instance adapter has been created for')
template = Attribute('The template to be used for this instance') template = Attribute('A template to be used for this instance')
aspect = Attribute('A dotted name that helps to store and retrieve the ' aspect = Attribute('A dotted name that helps to store and retrieve the '
'template.') 'template.')
def applyTemplate(*args, **kw): def applyTemplate(*args, **kw):
""" Apply the template using the instance's context. Note that this """ Apply the template using the instance's context. Note that this

View file

@ -0,0 +1,4 @@
"""
$Id$
"""

View file

@ -0,0 +1,34 @@
#
# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Basic browser view classes for composer.schema.
$Id$
"""
from zope.cachedescriptors.property import Lazy
from cybertools.composer.instance import Instance
class SchemaView(object):
@Lazy
def fields(self):
return self.context.fields

View file

@ -0,0 +1,19 @@
<!-- $Id$ -->
<configure
xmlns="http://namespaces.zope.org/browser"
xmlns:zope="http://namespaces.zope.org/zope"
i18n_domain="zope">
<page
for="cybertools.composer.schema.interfaces.ISchema"
name="index.html"
class="cybertools.composer.schema.browser.base.SchemaView"
permission="zope.View"
/>
<defaultView
name="index.html"
for="cybertools.composer.schema.interfaces.ISchema" />
</configure>

View file

@ -35,8 +35,15 @@ class Field(Component):
def __init__(self, name, title=None, renderFactory=None, **kw): def __init__(self, name, title=None, renderFactory=None, **kw):
assert name assert name
self.name = self.__name__ = name self.__name__ = name
title = title is None and name or title title = title or u''
self.renderFactory = renderFactory # use for rendering field content self.renderFactory = renderFactory # use for rendering field content
super(Field, self).__init__(title, __name__=name, **kw) super(Field, self).__init__(title, __name__=name, **kw)
@property
def name(self):
return self.__name__
@property
def title(self):
return self.title or self.name

View file

@ -38,6 +38,9 @@ class ISchema(ITemplate):
fields = Attribute('The components the schema is built up of. ' fields = Attribute('The components the schema is built up of. '
'Should be a sequence of IField objects.') 'Should be a sequence of IField objects.')
manager = Attribute('A manager object that may provide special '
'features, e.g. a factory of o')
class IField(IComponent): class IField(IComponent):
""" May be used for data entry or display. """ May be used for data entry or display.

View file

@ -33,7 +33,12 @@ class Schema(Template):
implements(ISchema) implements(ISchema)
def __init__(self, *fields): name = u''
manager = None
def __init__(self, *fields, **kw):
self.name = kw.get('name', u'')
self.manager = kw.get('manager', None)
super(Schema, self).__init__() super(Schema, self).__init__()
for f in fields: for f in fields:
self.components.append(f) self.components.append(f)

View file

@ -128,6 +128,18 @@ class IServiceManager(Interface):
services = Attribute('A collection of services managed by this object.') services = Attribute('A collection of services managed by this object.')
clients = Attribute('A collection of client objects (e.g. persons) '
'that have registered or want to register for '
'services managed by this service manager.')
clientSchemas = Attribute('An optional collection of schema objects '
'that describe the data fields of the client '
'objects.')
def addClient(client):
""" Add the client object given to the collection of clients.
"""
class IServiceGroup(Interface): class IServiceGroup(Interface):
""" A group of related services or a general service definition, """ A group of related services or a general service definition,
@ -183,6 +195,24 @@ class IScheduledService(IService):
duration = Attribute('Time delta between start and end date/time.') duration = Attribute('Time delta between start and end date/time.')
class IClient(Interface):
""" An fairly abstract interface for objects to be used as clients
for services.
"""
manager = Attribute('The object that cares for this client.')
class IClientFactory(Interface):
""" Creates client objects.
"""
def __call__(data):
""" Creates and returns a client object built from the
data set provided.
"""
class IRegistration(Interface): class IRegistration(Interface):
""" Information about the registration of a client with a service. """ Information about the registration of a client with a service.
""" """

View file

@ -22,9 +22,15 @@ Service management classes.
$Id$ $Id$
""" """
from BTrees.OOBTree import OOBTree
from zope.cachedescriptors.property import Lazy
from zope.component import adapts
from zope.interface import implements from zope.interface import implements
from cybertools.composer.interfaces import IInstance
from cybertools.util.jeep import Jeep
from cybertools.organize.interfaces import IServiceManager from cybertools.organize.interfaces import IServiceManager
from cybertools.organize.interfaces import IClient, IClientFactory
from cybertools.organize.interfaces import IService, IScheduledService from cybertools.organize.interfaces import IService, IScheduledService
@ -32,6 +38,30 @@ class ServiceManager(object):
implements(IServiceManager) implements(IServiceManager)
servicesFactory = list
clientSchemasFactory = Jeep
clientsFactory = OOBTree
clientNum = 0
def __init__(self):
if self.servicesFactory is not None:
self.services = self.servicesFactory()
if self.clientSchemasFactory is not None:
self.clientSchemas = self.clientSchemasFactory()
@Lazy
def clients(self):
return self.clientsFactory()
def addClient(self, client):
name = self.generateClientName(client)
self.clients[name] = client
def generateClientName(self, client):
self.clientNum += 1
return '%05i' % self.clientNum
class Service(object): class Service(object):
@ -60,6 +90,57 @@ class ScheduledService(Service):
implements(IScheduledService) implements(IScheduledService)
class Client(object):
implements(IClient)
def __init__(self, manager):
self.manager = manager
class ClientFactory(object):
implements(IClientFactory)
adapts(IServiceManager)
def __init__(self, context):
self.context = context
def __call__(self):
return Client(self.context)
class ClientInstanceAdapter(object):
implements(IInstance)
adapts(IClient)
baseAspect = 'service.client.'
schema = 'default'
@property
def aspect(self):
return self.baseAspect + self.schema
@property
def template(self):
return self.context.manager.clientSchemas.get(self.schema, None)
def __init__(self, context):
self.context = context
def applyTemplate(self, data={}, schema='default', **kw):
if getattr(self.context, 'attributes', None) is None:
self.context.attributes = OOBTree()
self.schema = schema
template = self.template
attributes = self.context.attributes.setdefault(self.aspect, OOBTree())
if template is not None:
for c in template.components:
name = c.name
attributes[name] = data.get(name, u'')
class Registration(object): class Registration(object):
def __init__(self, client): def __init__(self, client):

View file

@ -31,10 +31,10 @@ class Jeep(object):
_attributes = ('_sequence',) _attributes = ('_sequence',)
def __init__(self, seq=[]): def __init__(self, seq=[]):
self._sequence = [] sequence = self._sequence = []
for item in seq: for attr, value in seq:
attr, value = item sequence.append(attr)
setattr(self, attr, value) object.__setattr__(self, attr, value)
def __len__(self): def __len__(self):
return len(self._sequence) return len(self._sequence)
@ -47,11 +47,11 @@ class Jeep(object):
if not attr in self._attributes: if not attr in self._attributes:
if getattr(self, attr, _notfound) is _notfound: if getattr(self, attr, _notfound) is _notfound:
self._sequence.append(attr) self._sequence.append(attr)
object.__setattr__(self, attr, value) super(Jeep, self).__setattr__(attr, value)
def __delattr__(self, attr): def __delattr__(self, attr):
del self._sequence[self.index(attr)] del self._sequence[self.index(attr)]
object.__delattr__(self, attr) super(Jeep, self).__delattr__(attr)
def __getitem__(self, key): def __getitem__(self, key):
if type(key) in (int, long): if type(key) in (int, long):

View file

@ -21,26 +21,33 @@ A general purpose (thus 'Jeep') class that provides most of the interfaces
of sequences and dictionaries and in addition allows attribute access to of sequences and dictionaries and in addition allows attribute access to
the dictionary entries. the dictionary entries.
This is the Zope-based persistent variant of the Jeep class.
$Id$ $Id$
""" """
from persistent import Persistent
from persistent.list import PersistentList from persistent.list import PersistentList
from BTrees.OOBTree import OOBTree from BTrees.OOBTree import OOBTree
from zope.app.container.interfaces import IContainer
from zope.interface import implements
_notfound = object() _notfound = object()
_nodefault = object() _nodefault = object()
class Jeep(object): class Jeep(Persistent):
implements(IContainer)
_attributes = ('_sequence', '_mapping') _attributes = ('_sequence', '_mapping')
def __init__(self, seq=[]): def __init__(self, seq=[]):
self._sequence = PersistentList() sequence = self._sequence = PersistentList()
self._mapping = OOBTree() mapping = self._mapping = OOBTree()
for item in seq: for attr, value in seq:
attr, value = item sequence.append(attr)
setattr(self, attr, value) mapping[attr] = value
def __len__(self): def __len__(self):
return len(self._sequence) return len(self._sequence)
@ -60,7 +67,7 @@ class Jeep(object):
def __setattr__(self, attr, value): def __setattr__(self, attr, value):
if attr in self._attributes: if attr in self._attributes:
object.__setattr__(self, attr, value) super(Jeep, self).__setattr__(attr, value)
else: else:
if getattr(self, attr, _notfound) is _notfound: if getattr(self, attr, _notfound) is _notfound:
self._sequence.append(attr) self._sequence.append(attr)
@ -87,6 +94,8 @@ class Jeep(object):
def __contains__(self, key): def __contains__(self, key):
return getattr(self, key, _notfound) is not _notfound return getattr(self, key, _notfound) is not _notfound
has_key = __contains__
def keys(self): def keys(self):
return [key for key in self._sequence] return [key for key in self._sequence]