more on constraints: provide editable StaticConstraint
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2264 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
8577b09913
commit
209f5402f2
9 changed files with 126 additions and 35 deletions
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2006 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -88,6 +88,9 @@ class AdapterBase(object):
|
||||||
return False
|
return False
|
||||||
return self.context == other.context
|
return self.context == other.context
|
||||||
|
|
||||||
|
def getLoopsRoot(self):
|
||||||
|
return self.context.getLoopsRoot()
|
||||||
|
|
||||||
|
|
||||||
class ResourceAdapterBase(AdapterBase):
|
class ResourceAdapterBase(AdapterBase):
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ from zope.cachedescriptors.property import Lazy
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
from zope.interface import implements
|
from zope.interface import implements
|
||||||
from zope.interface import alsoProvides, directlyProvides, directlyProvidedBy
|
from zope.interface import alsoProvides, directlyProvides, directlyProvidedBy
|
||||||
from zope.security.proxy import removeSecurityProxy
|
from zope.security.proxy import removeSecurityProxy, isinstance
|
||||||
from zope.traversing.api import getName, getParent
|
from zope.traversing.api import getName, getParent
|
||||||
from persistent import Persistent
|
from persistent import Persistent
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ from cybertools.typology.interfaces import IType, ITypeManager
|
||||||
from cybertools.util.jeep import Jeep
|
from cybertools.util.jeep import Jeep
|
||||||
|
|
||||||
from loops.base import ParentInfo
|
from loops.base import ParentInfo
|
||||||
|
from loops.common import AdapterBase
|
||||||
from loops.interfaces import IConcept, IConceptRelation, IConceptView
|
from loops.interfaces import IConcept, IConceptRelation, IConceptView
|
||||||
from loops.interfaces import IConceptManager, IConceptManagerContained
|
from loops.interfaces import IConceptManager, IConceptManagerContained
|
||||||
from loops.interfaces import ILoopsContained
|
from loops.interfaces import ILoopsContained
|
||||||
|
@ -286,6 +287,9 @@ class ConceptTypeSourceList(object):
|
||||||
|
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
self.context = context
|
self.context = context
|
||||||
|
if isinstance(context, AdapterBase):
|
||||||
|
self.context = self.context.context
|
||||||
|
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return iter(self.conceptTypes)
|
return iter(self.conceptTypes)
|
||||||
|
@ -326,7 +330,7 @@ class PredicateSourceList(object):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.conceptTypes)
|
return len(self.predicates)
|
||||||
|
|
||||||
|
|
||||||
class IndexAttributes(object):
|
class IndexAttributes(object):
|
||||||
|
|
|
@ -467,41 +467,28 @@
|
||||||
component="loops.resource.ResourceTypeSourceList"
|
component="loops.resource.ResourceTypeSourceList"
|
||||||
name="loops.resourceTypeSource" />
|
name="loops.resourceTypeSource" />
|
||||||
|
|
||||||
|
<utility
|
||||||
|
provides="zope.schema.interfaces.IVocabularyFactory"
|
||||||
|
component="loops.concept.PredicateSourceList"
|
||||||
|
name="loops.predicateSource" />
|
||||||
|
|
||||||
<utility
|
<utility
|
||||||
provides="zope.schema.interfaces.IVocabularyFactory"
|
provides="zope.schema.interfaces.IVocabularyFactory"
|
||||||
component="loops.type.TypeInterfaceSourceList"
|
component="loops.type.TypeInterfaceSourceList"
|
||||||
name="loops.TypeInterfaceSource" />
|
name="loops.TypeInterfaceSource" />
|
||||||
|
|
||||||
<!--<vocabulary
|
|
||||||
factory="loops.concept.ConceptTypeSourceList"
|
|
||||||
name="loops.conceptTypeSource"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<vocabulary
|
|
||||||
factory="loops.resource.ResourceTypeSourceList"
|
|
||||||
name="loops.resourceTypeSource"
|
|
||||||
/>-->
|
|
||||||
|
|
||||||
<!--<vocabulary
|
|
||||||
factory="loops.type.TypeInterfaceSourceList"
|
|
||||||
name="loops.TypeInterfaceSource"
|
|
||||||
/>-->
|
|
||||||
|
|
||||||
<utility component="loops.concept.PredicateSourceList"
|
|
||||||
provides="zope.schema.interfaces.IVocabularyFactory"
|
|
||||||
name="loops.PredicateSource" />
|
|
||||||
|
|
||||||
|
|
||||||
<include package=".browser" />
|
<include package=".browser" />
|
||||||
<include package=".classifier" />
|
<include package=".classifier" />
|
||||||
|
<include package=".constraint" />
|
||||||
<include package=".i18n" />
|
<include package=".i18n" />
|
||||||
<include package=".integrator" />
|
<include package=".integrator" />
|
||||||
<include package=".knowledge" />
|
<include package=".knowledge" />
|
||||||
<include package=".organize" />
|
<include package=".organize" />
|
||||||
<include package=".process" />
|
<include package=".process" />
|
||||||
|
<include package=".rest" />
|
||||||
<include package=".search" />
|
<include package=".search" />
|
||||||
<include package=".versioning" />
|
<include package=".versioning" />
|
||||||
<include package=".xmlrpc" />
|
<include package=".xmlrpc" />
|
||||||
<include package=".rest" />
|
|
||||||
|
|
||||||
</configure>
|
</configure>
|
||||||
|
|
|
@ -4,3 +4,22 @@ loops - Linked Objects for Organization and Processing Services
|
||||||
|
|
||||||
($Id$)
|
($Id$)
|
||||||
|
|
||||||
|
>>> from zope import component
|
||||||
|
>>> from zope.traversing.api import getName
|
||||||
|
|
||||||
|
Let's set up a loops site with basic and example concepts and resources.
|
||||||
|
|
||||||
|
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
||||||
|
>>> site = placefulSetUp(True)
|
||||||
|
|
||||||
|
>>> from loops.tests.setup import TestSite
|
||||||
|
>>> t = TestSite(site)
|
||||||
|
>>> concepts, resources, views = t.setup()
|
||||||
|
|
||||||
|
|
||||||
|
Constraints - Restrict Predicates and Types for Concept and Resource Assignments
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
>>> from loops.constraint.base import StaticConstraint
|
||||||
|
>>> component.provideAdapter(StaticConstraint)
|
||||||
|
|
||||||
|
|
|
@ -23,3 +23,33 @@ for assignment as children or as concepts to resources.
|
||||||
$Id$
|
$Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from zope.cachedescriptors.property import Lazy
|
||||||
|
from zope.interface import implements
|
||||||
|
from zope.traversing.api import getName
|
||||||
|
|
||||||
|
from loops.common import AdapterBase
|
||||||
|
from loops.constraint.interfaces import IStaticConstraint
|
||||||
|
from loops.type import TypeInterfaceSourceList
|
||||||
|
|
||||||
|
|
||||||
|
TypeInterfaceSourceList.typeInterfaces += (IStaticConstraint,)
|
||||||
|
|
||||||
|
|
||||||
|
class StaticConstraint(AdapterBase):
|
||||||
|
|
||||||
|
_contextAttributes = AdapterBase._contextAttributes + ['relationType', 'cardinality']
|
||||||
|
_adapterAttributes = AdapterBase._adapterAttributes + ('predicates', 'types',)
|
||||||
|
|
||||||
|
implements(IStaticConstraint)
|
||||||
|
|
||||||
|
def getPredicates(self):
|
||||||
|
return getattr(self.context, '_predicates', [])
|
||||||
|
def setPredicates(self, value):
|
||||||
|
self.context._predicates = value
|
||||||
|
predicates = property(getPredicates, setPredicates)
|
||||||
|
|
||||||
|
def getTypes(self):
|
||||||
|
return getattr(self.context, '_types', [])
|
||||||
|
def setTypes(self, value):
|
||||||
|
self.context._types = value
|
||||||
|
types = property(getTypes, setTypes)
|
||||||
|
|
18
constraint/configure.zcml
Normal file
18
constraint/configure.zcml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<!-- $Id$ -->
|
||||||
|
|
||||||
|
<configure
|
||||||
|
xmlns:zope="http://namespaces.zope.org/zope"
|
||||||
|
xmlns:browser="http://namespaces.zope.org/browser"
|
||||||
|
i18n_domain="zope">
|
||||||
|
|
||||||
|
<zope:adapter
|
||||||
|
factory="loops.constraint.base.StaticConstraint"
|
||||||
|
trusted="True" />
|
||||||
|
<zope:class class="loops.constraint.base.StaticConstraint">
|
||||||
|
<require permission="zope.View"
|
||||||
|
interface="loops.constraint.interfaces.IStaticConstraint" />
|
||||||
|
<require permission="zope.ManageContent"
|
||||||
|
set_schema="loops.constraint.interfaces.IStaticConstraint" />
|
||||||
|
</zope:class>
|
||||||
|
|
||||||
|
</configure>
|
|
@ -29,6 +29,8 @@ $Id$
|
||||||
from zope.interface import Interface, Attribute
|
from zope.interface import Interface, Attribute
|
||||||
from zope import interface, component, schema
|
from zope import interface, component, schema
|
||||||
|
|
||||||
|
from loops.concept import Concept
|
||||||
|
from loops.interfaces import IConceptSchema
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,10 +40,10 @@ class IConstraint(Interface):
|
||||||
client object.
|
client object.
|
||||||
|
|
||||||
When the client object is a concept the constraint checks
|
When the client object is a concept the constraint checks
|
||||||
for child relations, if it is a resource it checks for concept
|
parent relations, if it is a resource it checks concept
|
||||||
relations. In order to check for allowed parent relations (on
|
relations. In order to check for allowed child relations
|
||||||
a concept only) you may specify ``relationType=parent``
|
on a concept only you may specify a relation type of ``child``
|
||||||
on the method calls.
|
as an additional argument for the method calls.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
client = Attribute('Object that will be checked for allowed relations.')
|
client = Attribute('Object that will be checked for allowed relations.')
|
||||||
|
@ -68,7 +70,7 @@ class IConstraint(Interface):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class IStaticConstraint(IConstraint):
|
class IStaticConstraint(IConceptSchema, IConstraint):
|
||||||
""" Provides a statically assigned contstraint setting.
|
""" Provides a statically assigned contstraint setting.
|
||||||
|
|
||||||
Typically used as a concept adapter for a persistent constraint
|
Typically used as a concept adapter for a persistent constraint
|
||||||
|
@ -76,11 +78,40 @@ class IStaticConstraint(IConstraint):
|
||||||
of allowed relationships.
|
of allowed relationships.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
relationType = schema.TextLine()
|
relationType = schema.Choice(
|
||||||
|
title=_(u'Relation type'),
|
||||||
|
description=_(u'Select the type of the relation for '
|
||||||
|
'which this constraint should be checked, '
|
||||||
|
'"default" meaning parent relations for concepts '
|
||||||
|
'and resource/concept relations for resources.'),
|
||||||
|
values=('default', 'child'),
|
||||||
|
default='default',
|
||||||
|
required=True,)
|
||||||
|
|
||||||
predicates = schema.List()
|
predicates = schema.List(
|
||||||
|
title=_(u'Predicates'),
|
||||||
|
description=_(u'Select the predicates that this '
|
||||||
|
'constraint should allow.'),
|
||||||
|
value_type=schema.Choice(
|
||||||
|
title=_(u'Predicate'),
|
||||||
|
source='loops.predicateSource'),
|
||||||
|
required=False,)
|
||||||
|
|
||||||
types = schema.List()
|
types = schema.List(
|
||||||
|
title=_(u'Target types'),
|
||||||
|
description=_(u'Select the types of the objects '
|
||||||
|
'that this constraints should allow.'),
|
||||||
|
value_type=schema.Choice(
|
||||||
|
title=_(u'Type'),
|
||||||
|
source='loops.conceptTypeSource'),
|
||||||
|
required=False,)
|
||||||
|
|
||||||
cardinality = schema.List()
|
cardinality = schema.Choice(
|
||||||
|
title=_(u'Cardinality'),
|
||||||
|
description=_(u'Select an entry that represents the '
|
||||||
|
'allowed number of assigned items as specified '
|
||||||
|
'by this constraint.'),
|
||||||
|
values=('0,*', '0,1', '1,*', '1,1'),
|
||||||
|
default='0,*',
|
||||||
|
required=True,)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2006 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,7 +24,6 @@ $Id$
|
||||||
|
|
||||||
from zope.interface import Interface, Attribute
|
from zope.interface import Interface, Attribute
|
||||||
from zope import interface, component, schema
|
from zope import interface, component, schema
|
||||||
from zope.app import zapi
|
|
||||||
from zope.i18nmessageid import MessageFactory
|
from zope.i18nmessageid import MessageFactory
|
||||||
from zope.security.proxy import removeSecurityProxy
|
from zope.security.proxy import removeSecurityProxy
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2006 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
Loading…
Add table
Reference in a new issue