support for old __rtags__ tls-sprint
authorsylvain.thenault@logilab.fr
Thu, 26 Mar 2009 21:03:20 +0100
branchtls-sprint
changeset 1154 9b23a6836c32
parent 1153 6a7636b32a97
child 1172 959b0e177660
support for old __rtags__
entities/__init__.py
entities/authobjs.py
entities/lib.py
entities/schemaobjs.py
entities/wfobjs.py
entity.py
web/views/baseforms.py
web/views/editforms.py
--- a/entities/__init__.py	Thu Mar 26 20:54:40 2009 +0100
+++ b/entities/__init__.py	Thu Mar 26 21:03:20 2009 +0100
@@ -23,36 +23,7 @@
     """an entity instance has e_schema automagically set on the class and
     instances have access to their issuing cursor
     """
-    id = 'Any'   
-    __rtags__ = {
-        'is' : ('generated', 'link'),
-        'is_instance_of' : ('generated', 'link'),
-        'identity' : ('generated', 'link'),
-        
-        # use primary and not generated for eid since it has to be an hidden
-        # field in edition
-        ('eid',                '*', 'subject'): 'primary',
-        ('creation_date',      '*', 'subject'): 'generated',
-        ('modification_date',  '*', 'subject'): 'generated',
-        ('has_text',           '*', 'subject'): 'generated',
-        
-        ('require_permission', '*', 'subject') : ('generated', 'link'),
-        ('owned_by',           '*', 'subject') : ('generated', 'link'),
-        ('created_by',         '*', 'subject') : ('generated', 'link'),
-        
-        ('wf_info_for',        '*', 'subject') : ('generated', 'link'),
-        ('wf_info_for',        '*', 'object')  : ('generated', 'link'),
-                 
-        ('description',        '*', 'subject'): 'secondary',
-
-        # XXX should be moved in their respective cubes
-        ('filed_under',        '*', 'subject') : ('generic', 'link'),
-        ('filed_under',        '*', 'object')  : ('generic', 'create'),
-        # generated since there is a componant to handle comments
-        ('comments',           '*', 'subject') : ('generated', 'link'),
-        ('comments',           '*', 'object')  : ('generated', 'link'),
-        }
-
+    id = 'Any'                    
     __implements__ = (IBreadCrumbs, IFeed)
     
     @classmethod
@@ -277,64 +248,11 @@
             tschema = rschema.subjects(cls.e_schema)[0]
             wdg = widget(cls.vreg, tschema, rschema, cls, 'object')
         return wdg
-    
+
+    @obsolete('use AutomaticEntityForm.relations_by_category')
     def relations_by_category(self, categories=None, permission=None):
-        if categories is not None:
-            if not isinstance(categories, (list, tuple, set, frozenset)):
-                categories = (categories,)
-            if not isinstance(categories, (set, frozenset)):
-                categories = frozenset(categories)
-        eschema, rtags  = self.e_schema, self.rtags
-        if self.has_eid():
-            eid = self.eid
-        else:
-            eid = None
-        for rschema, targetschemas, role in eschema.relation_definitions(True):
-            if rschema in ('identity', 'has_text'):
-                continue
-            # check category first, potentially lower cost than checking
-            # permission which may imply rql queries
-            if categories is not None:
-                targetschemas = [tschema for tschema in targetschemas
-                                 if rtags.get_tags(rschema.type, tschema.type, role).intersection(categories)]
-                if not targetschemas:
-                    continue
-            tags = rtags.get_tags(rschema.type, role=role)
-            if permission is not None:
-                # tag allowing to hijack the permission machinery when
-                # permission is not verifiable until the entity is actually
-                # created...
-                if eid is None and ('%s_on_new' % permission) in tags:
-                    yield (rschema, targetschemas, role)
-                    continue
-                if rschema.is_final():
-                    if not rschema.has_perm(self.req, permission, eid):
-                        continue
-                elif role == 'subject':
-                    if not ((eid is None and rschema.has_local_role(permission)) or
-                            rschema.has_perm(self.req, permission, fromeid=eid)):
-                        continue
-                    # on relation with cardinality 1 or ?, we need delete perm as well
-                    # if the relation is already set
-                    if (permission == 'add'
-                        and rschema.cardinality(eschema, targetschemas[0], role) in '1?'
-                        and self.has_eid() and self.related(rschema.type, role)
-                        and not rschema.has_perm(self.req, 'delete', fromeid=eid,
-                                                 toeid=self.related(rschema.type, role)[0][0])):
-                        continue
-                elif role == 'object':
-                    if not ((eid is None and rschema.has_local_role(permission)) or
-                            rschema.has_perm(self.req, permission, toeid=eid)):
-                        continue
-                    # on relation with cardinality 1 or ?, we need delete perm as well
-                    # if the relation is already set
-                    if (permission == 'add'
-                        and rschema.cardinality(targetschemas[0], eschema, role) in '1?'
-                        and self.has_eid() and self.related(rschema.type, role)
-                        and not rschema.has_perm(self.req, 'delete', toeid=eid,
-                                                 fromeid=self.related(rschema.type, role)[0][0])):
-                        continue
-            yield (rschema, targetschemas, role)
+        from cubicweb.web.views.editform import AutomaticEntityForm
+        return AutomaticEntityForm.relations_by_category(entity, categories, permission)
 
     def srelations_by_category(self, categories=None, permission=None):
         result = []
--- a/entities/authobjs.py	Thu Mar 26 20:54:40 2009 +0100
+++ b/entities/authobjs.py	Thu Mar 26 21:03:20 2009 +0100
@@ -13,7 +13,6 @@
 class EGroup(AnyEntity):
     id = 'EGroup'
     fetch_attrs, fetch_order = fetch_config(['name'])
-    __rtags__ = dict(in_group='create')
 
     def db_key_name(self):
         """XXX goa specific"""
@@ -24,18 +23,6 @@
     id = 'EUser'
     fetch_attrs, fetch_order = fetch_config(['login', 'firstname', 'surname'])
     
-    __rtags__ = { 'firstname'  : 'secondary',
-                  'surname'    : 'secondary',
-                  'last_login_time' : 'generated',
-                  'todo_by'    : 'create',
-                  'use_email'  : 'inlineview', # 'primary',
-                  'in_state'   : 'primary', 
-                  'in_group'   : 'primary', 
-                  ('owned_by', '*', 'object') : ('generated', 'link'),
-                  ('created_by','*','object') : ('generated', 'link'),
-                  ('bookmarked_by', '*', 'object'): ('generated', 'create'),
-                  }
-    
     # used by repository to check if  the user can log in or not
     AUTHENTICABLE_STATES = ('activated',)
 
--- a/entities/lib.py	Thu Mar 26 20:54:40 2009 +0100
+++ b/entities/lib.py	Thu Mar 26 21:03:20 2009 +0100
@@ -25,10 +25,6 @@
     id = 'EmailAddress'
     fetch_attrs, fetch_order = fetch_config(['address', 'alias', 'canonical'])
 
-    widgets = {
-        'address' : "EmailWidget",
-        }
-
     def dc_title(self):
         if self.alias:
             return '%s <%s>' % (self.alias, self.display_address())
@@ -94,13 +90,7 @@
 class EProperty(AnyEntity):
     id = 'EProperty'
 
-    fetch_attrs, fetch_order = fetch_config(['pkey', 'value'])
-
-    widgets = {
-        'pkey' : "PropertyKeyWidget",
-        'value' : "PropertyValueWidget",
-        }
-    
+    fetch_attrs, fetch_order = fetch_config(['pkey', 'value'])    
     rest_attr = 'pkey'
 
     def typed_value(self):
@@ -120,10 +110,6 @@
     """customized class for Bookmark entities"""
     id = 'Bookmark'
     fetch_attrs, fetch_order = fetch_config(['title', 'path'])
-    widgets = {
-        'path' : "StringWidget",
-        }
-    __rtags__ = {'path': 'primary'}
 
     def actual_url(self):
         url = self.req.build_url(self.path)
--- a/entities/schemaobjs.py	Thu Mar 26 20:54:40 2009 +0100
+++ b/entities/schemaobjs.py	Thu Mar 26 21:03:20 2009 +0100
@@ -1,7 +1,7 @@
 """schema definition related entities
 
 :organization: Logilab
-:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 """
 __docformat__ = "restructuredtext en"
@@ -17,14 +17,7 @@
 class EEType(AnyEntity):
     id = 'EEType'
     fetch_attrs, fetch_order = fetch_config(['name'])
-    __rtags__ = {
-        ('final',         '*', 'subject'): 'generated',
-        
-        ('state_of',      '*', 'object'): 'create',
-        ('transition_of', '*', 'object'): 'create',
-        ('from_entity',   '*', 'object'): 'link',
-        ('to_entity',     '*', 'object'): 'link',
-        }
+
     def dc_title(self):
         return self.req._(self.name)
     
@@ -47,11 +40,6 @@
 class ERType(AnyEntity):
     id = 'ERType'
     fetch_attrs, fetch_order = fetch_config(['name'])
-    __rtags__ = {
-        ('final',         '*', 'subject'): 'generated',
-        
-        ('relation_type', '*', 'object') : 'create',
-        }
     
     def dc_title(self):
         return self.req._(self.name)
@@ -100,11 +88,6 @@
 class ENFRDef(AnyEntity):
     id = 'ENFRDef'
     fetch_attrs = fetch_config(['cardinality'])[0]
-    __rtags__ = {
-        ('relation_type', 'ERType', 'subject') : 'inlineview',
-        ('from_entity', 'EEType', 'subject') : 'inlineview',
-        ('to_entity', 'EEType', 'subject') : 'inlineview',
-        }
     
     def dc_title(self):
         return u'%s %s %s' % (
@@ -171,10 +154,6 @@
     id = 'RQLExpression'
     fetch_attrs, fetch_order = fetch_config(['exprtype', 'mainvars', 'expression'])
 
-    widgets = {
-        'expression' : "StringWidget",
-        }
-
     def dc_title(self):
         return '%s(%s)' % (self.exprtype, self.expression or u'')
 
@@ -209,11 +188,6 @@
     id = 'EPermission'
     fetch_attrs, fetch_order = fetch_config(['name', 'label'])
 
-
-    __rtags__ = {
-        'require_group' : 'primary',
-        }
-
     def dc_title(self):
         if self.label:
             return '%s (%s)' % (self.req._(self.name), self.label)
--- a/entities/wfobjs.py	Thu Mar 26 20:54:40 2009 +0100
+++ b/entities/wfobjs.py	Thu Mar 26 21:03:20 2009 +0100
@@ -1,14 +1,14 @@
 """workflow definition and history related entities
 
 :organization: Logilab
-:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 """
 __docformat__ = "restructuredtext en"
 
 from cubicweb.entities import AnyEntity, fetch_config
 
-
+ 
 class Transition(AnyEntity):
     """customized class for Transition entities
 
@@ -17,9 +17,6 @@
     """
     id = 'Transition'
     fetch_attrs, fetch_order = fetch_config(['name'])
-    __rtags__ = {('destination_state',  '*', 'subject'):  'create',
-                 ('allowed_transition', '*', 'object') :  'create',
-                  }
                  
     def may_be_passed(self, eid, stateeid):
         """return true if the logged user may pass this transition
@@ -66,11 +63,7 @@
     id = 'State'
     fetch_attrs, fetch_order = fetch_config(['name'])
     rest_attr = 'eid'
-    
-    __rtags__ = {'destination_state' : 'create',
-                 'allowed_transition' : 'create'
-                 }
-    
+        
     def transitions(self, entity, desteid=None):
         rql = ('Any T,N,DS where S allowed_transition T, S eid %(x)s, '
                'T name N, T destination_state DS, '
--- a/entity.py	Thu Mar 26 20:54:40 2009 +0100
+++ b/entity.py	Thu Mar 26 21:03:20 2009 +0100
@@ -6,6 +6,8 @@
 """
 __docformat__ = "restructuredtext en"
 
+from warnings import warn
+
 from logilab.common import interface
 from logilab.common.compat import all
 from logilab.common.decorators import cached
@@ -39,164 +41,70 @@
     return '1'
 
 
-class RelationTags(object):
-    
-    MODE_TAGS = frozenset(('link', 'create'))
-    CATEGORY_TAGS = frozenset(('primary', 'secondary', 'generic', 'generated',
-                               'inlineview'))
+MODE_TAGS = set(('link', 'create'))
+CATEGORY_TAGS = set(('primary', 'secondary', 'generic', 'generated')) # , 'metadata'))
 
-    def __init__(self, eclass, tagdefs):
-        # XXX if a rtag is redefined in a subclass,
-        # the rtag of the base class overwrite the rtag of the subclass
-        self.eclass = eclass
-        self._tagdefs = {}
-        for relation, tags in tagdefs.iteritems():
-            # tags must become a set
-            if isinstance(tags, basestring):
-                tags = set((tags,))
-            elif not isinstance(tags, set):
-                tags = set(tags)
-            # relation must become a 3-uple (rtype, targettype, role)
-            if isinstance(relation, basestring):
-                self._tagdefs[(relation, '*', 'subject')] = tags
-                self._tagdefs[(relation, '*', 'object')] = tags
-            elif len(relation) == 1: # useful ?
-                self._tagdefs[(relation[0], '*', 'subject')] = tags
-                self._tagdefs[(relation[0], '*', 'object')] = tags
-            elif len(relation) == 2:
-                rtype, ttype = relation
-                ttype = bw_normalize_etype(ttype) # XXX bw compat
-                self._tagdefs[rtype, ttype, 'subject'] = tags
-                self._tagdefs[rtype, ttype, 'object'] = tags
-            elif len(relation) == 3:
-                relation = list(relation)  # XXX bw compat
-                relation[1] = bw_normalize_etype(relation[1])
-                self._tagdefs[tuple(relation)] = tags
-            else:
-                raise ValueError('bad rtag definition (%r)' % (relation,))
-        
+try:
+    from cubicweb.web.views.editforms import AutomaticEntityForm
+    from cubicweb.web.views.boxes import EditBox
 
-    def __initialize__(self):
-        # eclass.[*]schema are only set when registering
-        self.schema = self.eclass.schema
-        eschema = self.eschema = self.eclass.e_schema
-        rtags = self._tagdefs
-        # expand wildcards in rtags and add automatic tags
-        for rschema, tschemas, role in sorted(eschema.relation_definitions(True)):
-            rtype = rschema.type
-            star_tags = rtags.pop((rtype, '*', role), set())
-            for tschema in tschemas:
-                tags = rtags.setdefault((rtype, tschema.type, role), set(star_tags))
-                if role == 'subject':
-                    X, Y = eschema, tschema
-                    card = rschema.rproperty(X, Y, 'cardinality')[0]
-                    composed = rschema.rproperty(X, Y, 'composite') == 'object'
-                else:
-                    X, Y = tschema, eschema
-                    card = rschema.rproperty(X, Y, 'cardinality')[1]
-                    composed = rschema.rproperty(X, Y, 'composite') == 'subject'
-                # set default category tags if needed
-                if not tags & self.CATEGORY_TAGS:
-                    if card in '1+':
-                        if not rschema.is_final() and composed:
-                            category = 'generated'
-                        elif rschema.is_final() and (
-                            rschema.type.endswith('_format')
-                            or rschema.type.endswith('_encoding')):
-                            category = 'generated'
-                        else:
-                            category = 'primary'
-                    elif rschema.is_final():
-                        if (rschema.type.endswith('_format')
-                            or rschema.type.endswith('_encoding')):
-                            category = 'generated'
-                        else:
-                            category = 'secondary'
-                    else: 
-                        category = 'generic'
-                    tags.add(category)
-                if not tags & self.MODE_TAGS:
-                    if card in '?1':
-                        # by default, suppose link mode if cardinality doesn't allow
-                        # more than one relation
-                        mode = 'link'
-                    elif rschema.rproperty(X, Y, 'composite') == role:
-                        # if self is composed of the target type, create mode
-                        mode = 'create'
-                    else:
-                        # link mode by default
-                        mode = 'link'
-                    tags.add(mode)
-
-    def _default_target(self, rschema, role='subject'):
-        eschema = self.eschema
-        if role == 'subject':
-            return eschema.subject_relation(rschema).objects(eschema)[0]
-        else:
-            return eschema.object_relation(rschema).subjects(eschema)[0]
-
-    # dict compat
-    def __getitem__(self, key):
-        if isinstance(key, basestring):
-            key = (key,)
-        return self.get_tags(*key)
-
-    __contains__ = __getitem__
+    def dispatch_rtags(tags, rtype, role, stype, otype):
+        for tag in tags:
+            if tag in MODE_TAGS:
+                EditBox.rmode.set_rtag(tag, rtype, role, stype, otype)
+            elif tag in CATEGORY_TAGS:
+                AutomaticEntityForm.rcategories.set_rtag(tag, rtype, role, stype, otype)
+            elif tag == 'inlined':
+                AutomaticEntityForm.rinline.set_rtag(True, rtype, role, stype, otype)
+            else:
+                raise ValueError(tag)
+            
+except ImportError:
+    AutomaticEntityForm = None
     
-    def get_tags(self, rtype, targettype=None, role='subject'):
-        rschema = self.schema.rschema(rtype)
-        if targettype is None:
-            tschema = self._default_target(rschema, role)
-        else:
-            tschema = self.schema.eschema(targettype)
-        return self._tagdefs[(rtype, tschema.type, role)]
-
-    __call__ = get_tags
+    def dispatch_rtags(*args):
+        pass
     
-    def get_mode(self, rtype, targettype=None, role='subject'):
-        # XXX: should we make an assertion on rtype not being final ?
-        # assert not rschema.is_final()
-        tags = self.get_tags(rtype, targettype, role)
-        # do not change the intersection order !
-        modes = tags & self.MODE_TAGS
-        assert len(modes) == 1
-        return modes.pop()
-
-    def get_category(self, rtype, targettype=None, role='subject'):
-        tags = self.get_tags(rtype, targettype, role)
-        categories = tags & self.CATEGORY_TAGS
-        assert len(categories) == 1
-        return categories.pop()
-
-    def is_inlined(self, rtype, targettype=None, role='subject'):
-        # return set(('primary', 'secondary')) & self.get_tags(rtype, targettype)
-        return 'inlineview' in self.get_tags(rtype, targettype, role)
-
-
 class metaentity(type):
     """this metaclass sets the relation tags on the entity class
     and deals with the `widgets` attribute
     """
     def __new__(mcs, name, bases, classdict):
         # collect baseclass' rtags
-        tagdefs = {}
-        widgets = {}
-        for base in bases:
-            tagdefs.update(getattr(base, '__rtags__', {}))
-            widgets.update(getattr(base, 'widgets', {}))
-        # update with the class' own rtgas
-        tagdefs.update(classdict.get('__rtags__', {}))
-        widgets.update(classdict.get('widgets', {}))
-        # XXX decide whether or not it's a good idea to replace __rtags__
-        #     good point: transparent support for inheritance levels >= 2
-        #     bad point: we loose the information of which tags are specific
-        #                to this entity class
-        classdict['__rtags__'] = tagdefs
-        classdict['widgets'] = widgets
-        eclass = super(metaentity, mcs).__new__(mcs, name, bases, classdict)
-        # adds the "rtags" attribute
-        eclass.rtags = RelationTags(eclass, tagdefs)
-        return eclass
+        if '__rtags__' in classdict:
+            etype = classdict['id']
+            warn('%s: __rtags__ is deprecated' % name, DeprecationWarning)
+            for relation, tags in classdict.pop('__rtags__').iteritems():
+                # tags must become an iterable
+                if isinstance(tags, basestring):
+                    tags = (tags,)
+                # relation must become a 3-uple (rtype, targettype, role)
+                if isinstance(relation, basestring):
+                    dispatch_rtags(tags, relation, 'subject', etype, '*')
+                    dispatch_rtags(tags, relation, 'object', '*', etype)
+                elif len(relation) == 1: # useful ?
+                    dispatch_rtags(tags, relation[0], 'subject', etype, '*')
+                    dispatch_rtags(tags, relation[0], 'object', '*', etype)
+                elif len(relation) == 2:
+                    rtype, ttype = relation
+                    ttype = bw_normalize_etype(ttype) # XXX bw compat
+                    dispatch_rtags(tags, rtype, 'subject', etype, ttype)
+                    dispatch_rtags(tags, rtype, 'object', ttype, etype)
+                elif len(relation) == 3:
+                    rtype, ttype, role = relation
+                    ttype = bw_normalize_etype(ttype)
+                    if role == 'subject':
+                        dispatch_rtags(tags, rtype, 'subject', etype, ttype)
+                    else:
+                        dispatch_rtags(tags, rtype, 'object', ttype, etype)
+                else:
+                    raise ValueError('bad rtag definition (%r)' % (relation,))
+        if 'widgets' in classdict and AutomaticEntityForm is not None:
+            etype = classdict['id']
+            warn('%s: widgets is deprecated' % name, DeprecationWarning)
+            for relation, wdgname in classdict.pop('widgets').iteritems():
+                AutomaticEntityForm.rwidgets.set_rtag(wdgname, rtype, 'subject', etype)
+        return super(metaentity, mcs).__new__(mcs, name, bases, classdict)
 
 
 class Entity(AppRsetObject, dict):
@@ -273,7 +181,6 @@
         if mixins:
             cls.__bases__ = tuple(mixins + [p for p in cls.__bases__ if not p is object])
             cls.debug('plugged %s mixins on %s', mixins, etype)
-        cls.rtags.__initialize__()
     
     @classmethod
     def fetch_rql(cls, user, restriction=None, fetchattrs=None, mainvar='X',
--- a/web/views/baseforms.py	Thu Mar 26 20:54:40 2009 +0100
+++ b/web/views/baseforms.py	Thu Mar 26 21:03:20 2009 +0100
@@ -21,6 +21,7 @@
 from cubicweb.web.controller import NAV_FORM_PARAMETERS
 from cubicweb.web.widgets import checkbox, InputWidget, ComboBoxWidget
 from cubicweb.web.form import FormMixIn
+from cubicweb.web.views.editforms import AutomaticEntityForm
 
 _ = unicode
     
@@ -326,7 +327,7 @@
     # should_* method extracted to allow overriding
     
     def should_inline_relation_form(self, entity, rschema, targettype, role):
-        return entity.rtags.is_inlined(rschema, targettype, role)
+        return AutomaticForm.rinlined.etype_rtag(entity.id, role, rschema, targettype)
 
     def should_display_inline_relation_form(self, rschema, existant, card):
         return not existant and card in '1+'
@@ -428,7 +429,7 @@
     def should_inline_relation_form(self, entity, rschema, targettype, role):
         if rschema == self.rschema:
             return False
-        return entity.rtags.is_inlined(rschema, targettype, role)
+        return AutomaticForm.rinlined.etype_rtag(entity.id, role, rschema, targettype)
 
     @cached
     def keep_entity(self, entity):
--- a/web/views/editforms.py	Thu Mar 26 20:54:40 2009 +0100
+++ b/web/views/editforms.py	Thu Mar 26 21:03:20 2009 +0100
@@ -249,10 +249,11 @@
     def editable_attributes(self):
         """return a list of (relation schema, role) to edit for the entity
         """
-        return [(rschema, x) for rschema, _, x in self.relations_by_category(self.attrcategories, 'add')
-                if rschema != 'eid']
-    
-    def relations_by_category(self, categories=None, permission=None):
+        return [(rschema, x) for rschema, _, x in self.relations_by_category(
+            self.entity, self.attrcategories, 'add') if rschema != 'eid']
+
+    @classmethod
+    def relations_by_category(cls, entity, categories=None, permission=None):
         """return a list of (relation schema, target schemas, role) matching
         categories and permission
         """
@@ -261,11 +262,11 @@
                 categories = (categories,)
             if not isinstance(categories, (set, frozenset)):
                 categories = frozenset(categories)
-        eschema  = self.edited_entity.e_schema
-        rtags = self.rcategories
-        permsoverrides = self.rpermissions_overrides
-        if self.edited_entity.has_eid():
-            eid = self.edited_entity.eid
+        eschema  = entity.e_schema
+        rtags = cls.rcategories
+        permsoverrides = cls.rpermissions_overrides
+        if entity.has_eid():
+            eid = entity.eid
         else:
             eid = None
         for rschema, targetschemas, role in eschema.relation_definitions(True):
@@ -286,31 +287,31 @@
                     yield (rschema, targetschemas, role)
                     continue
                 if rschema.is_final():
-                    if not rschema.has_perm(self.req, permission, eid):
+                    if not rschema.has_perm(entity.req, permission, eid):
                         continue
                 elif role == 'subject':
                     if not ((eid is None and rschema.has_local_role(permission)) or
-                            rschema.has_perm(self.req, permission, fromeid=eid)):
+                            rschema.has_perm(entity.req, permission, fromeid=eid)):
                         continue
                     # on relation with cardinality 1 or ?, we need delete perm as well
                     # if the relation is already set
                     if (permission == 'add'
                         and rschema.cardinality(eschema, targetschemas[0], role) in '1?'
-                        and eid and self.edited_entity.related(rschema.type, role)
-                        and not rschema.has_perm(self.req, 'delete', fromeid=eid,
-                                                 toeid=self.edited_entity.related(rschema.type, role)[0][0])):
+                        and eid and entity.related(rschema.type, role)
+                        and not rschema.has_perm(entity.req, 'delete', fromeid=eid,
+                                                 toeid=entity.related(rschema.type, role)[0][0])):
                         continue
                 elif role == 'object':
                     if not ((eid is None and rschema.has_local_role(permission)) or
-                            rschema.has_perm(self.req, permission, toeid=eid)):
+                            rschema.has_perm(entity.req, permission, toeid=eid)):
                         continue
                     # on relation with cardinality 1 or ?, we need delete perm as well
                     # if the relation is already set
                     if (permission == 'add'
                         and rschema.cardinality(targetschemas[0], eschema, role) in '1?'
-                        and eid and self.edited_entity.related(rschema.type, role)
-                        and not rschema.has_perm(self.req, 'delete', toeid=eid,
-                                                 fromeid=self.edited_entity.related(rschema.type, role)[0][0])):
+                        and eid and entity.related(rschema.type, role)
+                        and not rschema.has_perm(entity.req, 'delete', toeid=eid,
+                                                 fromeid=entity.related(rschema.type, role)[0][0])):
                         continue
             yield (rschema, targetschemas, role)
     
@@ -321,8 +322,8 @@
         return a list of (relation's label, relation'schema, role)
         """
         result = []
-        for rschema, ttypes, role in self.relations_by_category(categories,
-                                                                permission):
+        for rschema, ttypes, role in self.relations_by_category(
+            self.entity, categories, permission):
             if rschema.is_final():
                 continue
             result.append( (rschema.display_name(self.req, role), rschema, role) )