diff -r 000000000000 -r b97547f5f1fa entities/schemaobjs.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/entities/schemaobjs.py Wed Nov 05 15:52:50 2008 +0100 @@ -0,0 +1,229 @@ +"""schema definition related entities + +:organization: Logilab +:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr +""" +__docformat__ = "restructuredtext en" + +from logilab.common.decorators import cached + +from cubicweb import ValidationError +from cubicweb.schema import ERQLExpression, RRQLExpression + +from cubicweb.entities import AnyEntity, fetch_config + + +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) + + def dc_long_title(self): + stereotypes = [] + _ = self.req._ + if self.meta: + stereotypes.append(_('meta')) + if self.final: + stereotypes.append(_('final')) + if stereotypes: + return u'%s <<%s>>' % (self.dc_title(), ', '.join(stereotypes)) + return self.dc_title() + + def db_key_name(self): + """XXX goa specific""" + return self.get('name') + + +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) + + def dc_long_title(self): + stereotypes = [] + _ = self.req._ + if self.meta: + stereotypes.append(_('meta')) + if self.symetric: + stereotypes.append(_('symetric')) + if self.inlined: + stereotypes.append(_('inlined')) + if self.final: + stereotypes.append(_('final')) + if stereotypes: + return u'%s <<%s>>' % (self.dc_title(), ', '.join(stereotypes)) + return self.dc_title() + + def inlined_changed(self, inlined): + """check inlining is necessary and possible: + + * return False if nothing has changed + * raise ValidationError if inlining is'nt possible + * eventually return True + """ + rtype = self.name + rschema = self.schema.rschema(rtype) + if inlined == rschema.inlined: + return False + if inlined: + for (stype, otype) in rschema.iter_rdefs(): + card = rschema.rproperty(stype, otype, 'cardinality')[0] + if not card in '?1': + msg = self.req._("can't set inlined=%(inlined)s, " + "%(stype)s %(rtype)s %(otype)s " + "has cardinality=%(card)s") + raise ValidationError(self.eid, {'inlined': msg % locals()}) + return True + + def db_key_name(self): + """XXX goa specific""" + return self.get('name') + + +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' % ( + self.from_entity[0].name, + self.relation_type[0].name, + self.to_entity[0].name) + + def dc_long_title(self): + card = self.cardinality + scard, ocard = u'', u'' + if card[0] != '1': + scard = '[%s]' % card[0] + if card[1] != '1': + ocard = '[%s]' % card[1] + return u'%s %s%s%s %s' % ( + self.from_entity[0].name, + scard, self.relation_type[0].name, ocard, + self.to_entity[0].name) + + def after_deletion_path(self): + """return (path, parameters) which should be used as redirect + information when this entity is being deleted + """ + if self.relation_type: + return self.relation_type[0].rest_path(), {} + return super(ENFRDef, self).after_deletion_path() + + +class EFRDef(ENFRDef): + id = 'EFRDef' + + def dc_long_title(self): + card = self.cardinality + scard = u'' + if card[0] == '1': + scard = '+' + return u'%s %s%s %s' % ( + self.from_entity[0].name, + scard, self.relation_type[0].name, + self.to_entity[0].name) + + +class EConstraint(AnyEntity): + id = 'EConstraint' + fetch_attrs, fetch_order = fetch_config(['value']) + + def dc_title(self): + return '%s(%s)' % (self.cstrtype[0].name, self.value or u'') + + def after_deletion_path(self): + """return (path, parameters) which should be used as redirect + information when this entity is being deleted + """ + if self.reverse_constrained_by: + return self.reverse_constrained_by[0].rest_path(), {} + return super(EConstraint, self).after_deletion_path() + + @property + def type(self): + return self.cstrtype[0].name + + +class RQLExpression(AnyEntity): + 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'') + + @property + def expression_of(self): + for rel in ('read_permission', 'add_permission', 'delete_permission', + 'update_permission', 'condition'): + values = getattr(self, 'reverse_%s' % rel) + if values: + return values[0] + + @cached + def _rqlexpr(self): + if self.exprtype == 'ERQLExpression': + return ERQLExpression(self.expression, self.mainvars, self.eid) + #if self.exprtype == 'RRQLExpression': + return RRQLExpression(self.expression, self.mainvars, self.eid) + + def check_expression(self, *args, **kwargs): + return self._rqlexpr().check(*args, **kwargs) + + def after_deletion_path(self): + """return (path, parameters) which should be used as redirect + information when this entity is being deleted + """ + if self.expression_of: + return self.expression_of.rest_path(), {} + return super(RQLExpression, self).after_deletion_path() + + +class EPermission(AnyEntity): + 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) + return self.req._(self.name) + + def after_deletion_path(self): + """return (path, parameters) which should be used as redirect + information when this entity is being deleted + """ + permissionof = getattr(self, 'reverse_require_permission', ()) + if len(permissionof) == 1: + return permissionof[0].rest_path(), {} + return super(EPermission, self).after_deletion_path()