entities/schemaobjs.py
changeset 0 b97547f5f1fa
child 1154 9b23a6836c32
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 """schema definition related entities
       
     2 
       
     3 :organization: Logilab
       
     4 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     6 """
       
     7 __docformat__ = "restructuredtext en"
       
     8 
       
     9 from logilab.common.decorators import cached
       
    10 
       
    11 from cubicweb import ValidationError
       
    12 from cubicweb.schema import ERQLExpression, RRQLExpression
       
    13 
       
    14 from cubicweb.entities import AnyEntity, fetch_config
       
    15 
       
    16 
       
    17 class EEType(AnyEntity):
       
    18     id = 'EEType'
       
    19     fetch_attrs, fetch_order = fetch_config(['name'])
       
    20     __rtags__ = {
       
    21         ('final',         '*', 'subject'): 'generated',
       
    22         
       
    23         ('state_of',      '*', 'object'): 'create',
       
    24         ('transition_of', '*', 'object'): 'create',
       
    25         ('from_entity',   '*', 'object'): 'link',
       
    26         ('to_entity',     '*', 'object'): 'link',
       
    27         }
       
    28     def dc_title(self):
       
    29         return self.req._(self.name)
       
    30     
       
    31     def dc_long_title(self):
       
    32         stereotypes = []
       
    33         _ = self.req._
       
    34         if self.meta:
       
    35             stereotypes.append(_('meta'))
       
    36         if self.final:
       
    37             stereotypes.append(_('final'))
       
    38         if stereotypes:
       
    39             return u'%s <<%s>>' % (self.dc_title(), ', '.join(stereotypes))
       
    40         return self.dc_title()
       
    41 
       
    42     def db_key_name(self):
       
    43         """XXX goa specific"""
       
    44         return self.get('name')
       
    45 
       
    46 
       
    47 class ERType(AnyEntity):
       
    48     id = 'ERType'
       
    49     fetch_attrs, fetch_order = fetch_config(['name'])
       
    50     __rtags__ = {
       
    51         ('final',         '*', 'subject'): 'generated',
       
    52         
       
    53         ('relation_type', '*', 'object') : 'create',
       
    54         }
       
    55     
       
    56     def dc_title(self):
       
    57         return self.req._(self.name)
       
    58     
       
    59     def dc_long_title(self):
       
    60         stereotypes = []
       
    61         _ = self.req._
       
    62         if self.meta:
       
    63             stereotypes.append(_('meta'))
       
    64         if self.symetric:
       
    65             stereotypes.append(_('symetric'))
       
    66         if self.inlined:
       
    67             stereotypes.append(_('inlined'))
       
    68         if self.final:
       
    69             stereotypes.append(_('final'))
       
    70         if stereotypes:
       
    71             return u'%s <<%s>>' % (self.dc_title(), ', '.join(stereotypes))
       
    72         return self.dc_title()
       
    73 
       
    74     def inlined_changed(self, inlined):
       
    75         """check inlining is necessary and possible:
       
    76         
       
    77         * return False if nothing has changed
       
    78         * raise ValidationError if inlining is'nt possible
       
    79         * eventually return True
       
    80         """
       
    81         rtype = self.name
       
    82         rschema = self.schema.rschema(rtype)
       
    83         if inlined == rschema.inlined:
       
    84             return False
       
    85         if inlined:
       
    86             for (stype, otype) in rschema.iter_rdefs():
       
    87                 card = rschema.rproperty(stype, otype, 'cardinality')[0]
       
    88                 if not card in '?1':
       
    89                     msg = self.req._("can't set inlined=%(inlined)s, "
       
    90                                      "%(stype)s %(rtype)s %(otype)s "
       
    91                                      "has cardinality=%(card)s")
       
    92                     raise ValidationError(self.eid, {'inlined': msg % locals()})
       
    93         return True
       
    94 
       
    95     def db_key_name(self):
       
    96         """XXX goa specific"""
       
    97         return self.get('name')
       
    98 
       
    99 
       
   100 class ENFRDef(AnyEntity):
       
   101     id = 'ENFRDef'
       
   102     fetch_attrs = fetch_config(['cardinality'])[0]
       
   103     __rtags__ = {
       
   104         ('relation_type', 'ERType', 'subject') : 'inlineview',
       
   105         ('from_entity', 'EEType', 'subject') : 'inlineview',
       
   106         ('to_entity', 'EEType', 'subject') : 'inlineview',
       
   107         }
       
   108     
       
   109     def dc_title(self):
       
   110         return u'%s %s %s' % (
       
   111             self.from_entity[0].name,
       
   112             self.relation_type[0].name, 
       
   113             self.to_entity[0].name)
       
   114     
       
   115     def dc_long_title(self):
       
   116         card = self.cardinality
       
   117         scard, ocard = u'', u''
       
   118         if card[0] != '1':
       
   119             scard = '[%s]' % card[0]
       
   120         if card[1] != '1':
       
   121             ocard = '[%s]' % card[1]
       
   122         return u'%s %s%s%s %s' % (
       
   123             self.from_entity[0].name,
       
   124             scard, self.relation_type[0].name, ocard,
       
   125             self.to_entity[0].name)
       
   126 
       
   127     def after_deletion_path(self):
       
   128         """return (path, parameters) which should be used as redirect
       
   129         information when this entity is being deleted
       
   130         """
       
   131         if self.relation_type:
       
   132             return self.relation_type[0].rest_path(), {}
       
   133         return super(ENFRDef, self).after_deletion_path()
       
   134 
       
   135 
       
   136 class EFRDef(ENFRDef):
       
   137     id = 'EFRDef'
       
   138     
       
   139     def dc_long_title(self):
       
   140         card = self.cardinality
       
   141         scard = u''
       
   142         if card[0] == '1':
       
   143             scard = '+'
       
   144         return u'%s %s%s %s' % (
       
   145             self.from_entity[0].name,
       
   146             scard, self.relation_type[0].name, 
       
   147             self.to_entity[0].name)
       
   148 
       
   149 
       
   150 class EConstraint(AnyEntity):
       
   151     id = 'EConstraint'
       
   152     fetch_attrs, fetch_order = fetch_config(['value'])
       
   153 
       
   154     def dc_title(self):
       
   155         return '%s(%s)' % (self.cstrtype[0].name, self.value or u'')
       
   156         
       
   157     def after_deletion_path(self):
       
   158         """return (path, parameters) which should be used as redirect
       
   159         information when this entity is being deleted
       
   160         """
       
   161         if self.reverse_constrained_by:
       
   162             return self.reverse_constrained_by[0].rest_path(), {}
       
   163         return super(EConstraint, self).after_deletion_path()
       
   164 
       
   165     @property
       
   166     def type(self):
       
   167         return self.cstrtype[0].name
       
   168 
       
   169         
       
   170 class RQLExpression(AnyEntity):
       
   171     id = 'RQLExpression'
       
   172     fetch_attrs, fetch_order = fetch_config(['exprtype', 'mainvars', 'expression'])
       
   173 
       
   174     widgets = {
       
   175         'expression' : "StringWidget",
       
   176         }
       
   177 
       
   178     def dc_title(self):
       
   179         return '%s(%s)' % (self.exprtype, self.expression or u'')
       
   180 
       
   181     @property
       
   182     def expression_of(self):
       
   183         for rel in ('read_permission', 'add_permission', 'delete_permission',
       
   184                     'update_permission', 'condition'):
       
   185             values = getattr(self, 'reverse_%s' % rel)
       
   186             if values:
       
   187                 return values[0]
       
   188             
       
   189     @cached
       
   190     def _rqlexpr(self):
       
   191         if self.exprtype == 'ERQLExpression':
       
   192             return ERQLExpression(self.expression, self.mainvars, self.eid)
       
   193         #if self.exprtype == 'RRQLExpression':
       
   194         return RRQLExpression(self.expression, self.mainvars, self.eid)
       
   195     
       
   196     def check_expression(self, *args, **kwargs):
       
   197         return self._rqlexpr().check(*args, **kwargs)
       
   198     
       
   199     def after_deletion_path(self):
       
   200         """return (path, parameters) which should be used as redirect
       
   201         information when this entity is being deleted
       
   202         """
       
   203         if self.expression_of:
       
   204             return self.expression_of.rest_path(), {}
       
   205         return super(RQLExpression, self).after_deletion_path()
       
   206 
       
   207 
       
   208 class EPermission(AnyEntity):
       
   209     id = 'EPermission'
       
   210     fetch_attrs, fetch_order = fetch_config(['name', 'label'])
       
   211 
       
   212 
       
   213     __rtags__ = {
       
   214         'require_group' : 'primary',
       
   215         }
       
   216 
       
   217     def dc_title(self):
       
   218         if self.label:
       
   219             return '%s (%s)' % (self.req._(self.name), self.label)
       
   220         return self.req._(self.name)
       
   221     
       
   222     def after_deletion_path(self):
       
   223         """return (path, parameters) which should be used as redirect
       
   224         information when this entity is being deleted
       
   225         """
       
   226         permissionof = getattr(self, 'reverse_require_permission', ())
       
   227         if len(permissionof) == 1:
       
   228             return permissionof[0].rest_path(), {}
       
   229         return super(EPermission, self).after_deletion_path()