[entity] introduce a new 'adapters' registry
This changeset introduces the notion in adapters (as in Zope Component Architecture)
in a cubicweb way, eg using a specific registry of appobjects.
This allows nicer code structure, by avoid clutering entity classes and moving
code usually specific to a place of the ui (or something else) together with the
code that use the interface.
We don't use actual interface anymore, they are implied by adapters (which
may be abstract), whose reg id is an interface name.
Appobjects that used to 'implements(IFace)' should now be rewritten by:
* coding an IFaceAdapter(EntityAdapter) defining (implementing if desired)
the interface, usually with __regid__ = 'IFace'
* use "adaptable('IFace')" as selector instead
Also, the implements_adapter_compat decorator eases backward compatibility
with adapter's methods that may still be found on entities implementing
the interface.
Notice that unlike ZCA, we don't support automatic adapters chain (yagni?).
All interfaces defined in cubicweb have been turned into adapters, also
some new ones have been introduced to cleanup Entity / AnyEntity classes
namespace. At the end, the pluggable mixins mecanism should disappear in
favor of adapters as well.
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr## This file is part of CubicWeb.## CubicWeb is free software: you can redistribute it and/or modify it under the# terms of the GNU Lesser General Public License as published by the Free# Software Foundation, either version 2.1 of the License, or (at your option)# any later version.## CubicWeb 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 Lesser General Public License for more# details.## You should have received a copy of the GNU Lesser General Public License along# with CubicWeb. If not, see <http://www.gnu.org/licenses/>."""core CubicWeb schema necessary for bootstrapping the actual instance's schema"""__docformat__="restructuredtext en"_=unicodefromyams.buildobjsimport(EntityType,RelationType,RelationDefinition,SubjectRelation,RichString,String,Boolean,Int)fromcubicweb.schemaimport(RQLConstraint,PUB_SYSTEM_ENTITY_PERMS,PUB_SYSTEM_REL_PERMS,PUB_SYSTEM_ATTR_PERMS)# not restricted since as "is" is handled as other relations, guests need# access to thisclassCWEType(EntityType):"""define an entity type, used to build the instance schema"""__permissions__=PUB_SYSTEM_ENTITY_PERMSname=String(required=True,indexed=True,internationalizable=True,unique=True,maxsize=64)description=RichString(internationalizable=True,description=_('semantic description of this entity type'))# necessary to filter using RQLfinal=Boolean(description=_('automatic'))classCWRType(EntityType):"""define a relation type, used to build the instance schema"""__permissions__=PUB_SYSTEM_ENTITY_PERMSname=String(required=True,indexed=True,internationalizable=True,unique=True,maxsize=64)description=RichString(internationalizable=True,description=_('semantic description of this relation type'))symmetric=Boolean(description=_('is this relation equivalent in both direction ?'))inlined=Boolean(description=_('is this relation physically inlined? you should know what you\'re doing if you are changing this!'))fulltext_container=String(description=_('if full text content of subject/object entity ''should be added to other side entity (the container).'),vocabulary=('',_('subject'),_('object')),maxsize=8,default=None)final=Boolean(description=_('automatic'))classCWAttribute(EntityType):"""define a final relation: link a final relation type from a non final entity to a final entity type. used to build the instance schema """__permissions__=PUB_SYSTEM_ENTITY_PERMSrelation_type=SubjectRelation('CWRType',cardinality='1*',constraints=[RQLConstraint('O final TRUE')],composite='object')from_entity=SubjectRelation('CWEType',cardinality='1*',constraints=[RQLConstraint('O final FALSE')],composite='object')to_entity=SubjectRelation('CWEType',cardinality='1*',constraints=[RQLConstraint('O final TRUE')],composite='object')constrained_by=SubjectRelation('CWConstraint',cardinality='*1',composite='subject')cardinality=String(maxsize=2,internationalizable=True,vocabulary=[_('?1'),_('11')],description=_('subject/object cardinality'))ordernum=Int(description=('control subject entity\'s relations order'),default=0)indexed=Boolean(description=_('create an index for quick search on this attribute'))fulltextindexed=Boolean(description=_('index this attribute\'s value in the plain text index'))internationalizable=Boolean(description=_('is this attribute\'s value translatable'))defaultval=String(maxsize=256)description=RichString(internationalizable=True,description=_('semantic description of this attribute'))CARDINALITY_VOCAB=[_('?*'),_('1*'),_('+*'),_('**'),_('?+'),_('1+'),_('++'),_('*+'),_('?1'),_('11'),_('+1'),_('*1'),_('??'),_('1?'),_('+?'),_('*?')]classCWRelation(EntityType):"""define a non final relation: link a non final relation type from a non final entity to a non final entity type. used to build the instance schema """__permissions__=PUB_SYSTEM_ENTITY_PERMSrelation_type=SubjectRelation('CWRType',cardinality='1*',constraints=[RQLConstraint('O final FALSE')],composite='object')from_entity=SubjectRelation('CWEType',cardinality='1*',constraints=[RQLConstraint('O final FALSE')],composite='object')to_entity=SubjectRelation('CWEType',cardinality='1*',constraints=[RQLConstraint('O final FALSE')],composite='object')constrained_by=SubjectRelation('CWConstraint',cardinality='*1',composite='subject')cardinality=String(maxsize=2,internationalizable=True,vocabulary=CARDINALITY_VOCAB,description=_('subject/object cardinality'))ordernum=Int(description=_('control subject entity\'s relations order'),default=0)composite=String(description=_('is the subject/object entity of the relation ''composed of the other ? This implies that when ''the composite is deleted, composants are also ''deleted.'),vocabulary=('',_('subject'),_('object')),maxsize=8,default=None)description=RichString(internationalizable=True,description=_('semantic description of this relation'))# not restricted since it has to be read when checking allowed transitionsclassRQLExpression(EntityType):"""define a rql expression used to define permissions"""__permissions__=PUB_SYSTEM_ENTITY_PERMSexprtype=String(required=True,vocabulary=['ERQLExpression','RRQLExpression'])mainvars=String(maxsize=8,description=_('name of the main variables which should be ''used in the selection if necessary (comma ''separated)'))expression=String(required=True,description=_('restriction part of a rql query. ''For entity rql expression, X and U are ''predefined respectivly to the current object and to ''the request user. For relation rql expression, ''S, O and U are predefined respectivly to the current ''relation\'subject, object and to ''the request user. '))classCWConstraint(EntityType):"""define a schema constraint"""__permissions__=PUB_SYSTEM_ENTITY_PERMScstrtype=SubjectRelation('CWConstraintType',cardinality='1*')value=String(description=_('depends on the constraint type'))classCWConstraintType(EntityType):"""define a schema constraint type"""__permissions__=PUB_SYSTEM_ENTITY_PERMSname=String(required=True,indexed=True,internationalizable=True,unique=True,maxsize=64)# not restricted since it has to be read when checking allowed transitionsclassCWGroup(EntityType):"""define a CubicWeb users group"""__permissions__=PUB_SYSTEM_ENTITY_PERMSname=String(required=True,indexed=True,internationalizable=True,unique=True,maxsize=64)classCWProperty(EntityType):"""used for cubicweb configuration. Once a property has been created you can't change the key. """__permissions__={'read':('managers','users','guests'),'add':('managers','users',),'update':('managers','owners',),'delete':('managers','owners',),}# key is a reserved word for mysqlpkey=String(required=True,internationalizable=True,maxsize=256,description=_('defines what\'s the property is applied for. ''You must select this first to be able to set ''value'))value=String(internationalizable=True,maxsize=256)classrelation_type(RelationType):"""link a relation definition to its relation type"""__permissions__=PUB_SYSTEM_REL_PERMSinlined=Trueclassfrom_entity(RelationType):"""link a relation definition to its subject entity type"""__permissions__=PUB_SYSTEM_REL_PERMSinlined=Trueclassto_entity(RelationType):"""link a relation definition to its object entity type"""__permissions__=PUB_SYSTEM_REL_PERMSinlined=Trueclassconstrained_by(RelationType):"""constraints applying on this relation"""__permissions__=PUB_SYSTEM_REL_PERMSclasscstrtype(RelationType):"""constraint factory"""__permissions__=PUB_SYSTEM_REL_PERMSinlined=Trueclassread_permission_cwgroup(RelationDefinition):"""groups allowed to read entities/relations of this type"""__permissions__=PUB_SYSTEM_REL_PERMSname='read_permission'subject=('CWEType','CWAttribute','CWRelation')object='CWGroup'cardinality='**'classadd_permission_cwgroup(RelationDefinition):"""groups allowed to add entities/relations of this type"""__permissions__=PUB_SYSTEM_REL_PERMSname='add_permission'subject=('CWEType','CWRelation')object='CWGroup'cardinality='**'classdelete_permission_cwgroup(RelationDefinition):"""groups allowed to delete entities/relations of this type"""__permissions__=PUB_SYSTEM_REL_PERMSname='delete_permission'subject=('CWEType','CWRelation')object='CWGroup'cardinality='**'classupdate_permission_cwgroup(RelationDefinition):"""groups allowed to update entities/relations of this type"""__permissions__=PUB_SYSTEM_REL_PERMSname='update_permission'subject=('CWEType','CWAttribute')object='CWGroup'cardinality='**'classread_permission_rqlexpr(RelationDefinition):"""rql expression allowing to read entities/relations of this type"""__permissions__=PUB_SYSTEM_REL_PERMSname='read_permission'subject=('CWEType','CWAttribute','CWRelation')object='RQLExpression'cardinality='*?'composite='subject'classadd_permission_rqlexpr(RelationDefinition):"""rql expression allowing to add entities/relations of this type"""__permissions__=PUB_SYSTEM_REL_PERMSname='add_permission'subject=('CWEType','CWRelation')object='RQLExpression'cardinality='*?'composite='subject'classdelete_permission_rqlexpr(RelationDefinition):"""rql expression allowing to delete entities/relations of this type"""__permissions__=PUB_SYSTEM_REL_PERMSname='delete_permission'subject=('CWEType','CWRelation')object='RQLExpression'cardinality='*?'composite='subject'classupdate_permission_rqlexpr(RelationDefinition):"""rql expression allowing to update entities/relations of this type"""__permissions__=PUB_SYSTEM_REL_PERMSname='update_permission'subject=('CWEType','CWAttribute')object='RQLExpression'cardinality='*?'composite='subject'classis_(RelationType):"""core relation indicating the type of an entity """name='is'# don't explicitly set composite here, this is handled anyway#composite = 'object'__permissions__={'read':('managers','users','guests'),'add':(),'delete':(),}cardinality='1*'subject='*'object='CWEType'classis_instance_of(RelationType):"""core relation indicating the types (including specialized types) of an entity """# don't explicitly set composite here, this is handled anyway#composite = 'object'__permissions__={'read':('managers','users','guests'),'add':(),'delete':(),}cardinality='+*'subject='*'object='CWEType'classspecializes(RelationType):name='specializes'__permissions__={'read':('managers','users','guests'),'add':('managers',),'delete':('managers',),}cardinality='?*'subject='CWEType'object='CWEType'defpost_build_callback(schema):"""set attributes permissions for schema/workflow entities"""fromcubicweb.schemaimportSCHEMA_TYPES,WORKFLOW_TYPES,META_RTYPESwftypes=WORKFLOW_TYPES-set(('TrInfo',))foreschemainschema.entities():ifeschemainSCHEMA_TYPESoreschemainwftypes:forrschemaineschema.subject_relations():ifrschema.finalandnotrschemainMETA_RTYPES:rdef=eschema.rdef(rschema)rdef.permissions=PUB_SYSTEM_ATTR_PERMS