1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
3 # |
|
4 # This file is part of CubicWeb. |
|
5 # |
|
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
7 # terms of the GNU Lesser General Public License as published by the Free |
|
8 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
9 # any later version. |
|
10 # |
|
11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
|
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
14 # details. |
|
15 # |
|
16 # You should have received a copy of the GNU Lesser General Public License along |
|
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
18 """schema definition related entities""" |
|
19 |
|
20 __docformat__ = "restructuredtext en" |
|
21 |
|
22 from logilab.common.decorators import cached |
|
23 |
|
24 from yams.schema import role_name |
|
25 |
|
26 from cubicweb import ValidationError |
|
27 from cubicweb.schema import ERQLExpression, RRQLExpression |
|
28 |
|
29 from cubicweb.entities import AnyEntity, fetch_config |
|
30 |
|
31 |
|
32 class CWEType(AnyEntity): |
|
33 __regid__ = 'CWEType' |
|
34 fetch_attrs, cw_fetch_order = fetch_config(['name']) |
|
35 |
|
36 def dc_title(self): |
|
37 return u'%s (%s)' % (self.name, self._cw._(self.name)) |
|
38 |
|
39 def dc_long_title(self): |
|
40 stereotypes = [] |
|
41 _ = self._cw._ |
|
42 if self.final: |
|
43 stereotypes.append(_('final')) |
|
44 if stereotypes: |
|
45 return u'%s <<%s>>' % (self.dc_title(), ', '.join(stereotypes)) |
|
46 return self.dc_title() |
|
47 |
|
48 |
|
49 class CWRType(AnyEntity): |
|
50 __regid__ = 'CWRType' |
|
51 fetch_attrs, cw_fetch_order = fetch_config(['name']) |
|
52 |
|
53 def dc_title(self): |
|
54 return u'%s (%s)' % (self.name, self._cw._(self.name)) |
|
55 |
|
56 def dc_long_title(self): |
|
57 stereotypes = [] |
|
58 _ = self._cw._ |
|
59 if self.symmetric: |
|
60 stereotypes.append(_('symmetric')) |
|
61 if self.inlined: |
|
62 stereotypes.append(_('inlined')) |
|
63 if self.final: |
|
64 stereotypes.append(_('final')) |
|
65 if stereotypes: |
|
66 return u'%s <<%s>>' % (self.dc_title(), ', '.join(stereotypes)) |
|
67 return self.dc_title() |
|
68 |
|
69 def check_inlined_allowed(self): |
|
70 """check inlining is possible, raise ValidationError if not possible |
|
71 """ |
|
72 # don't use the persistent schema, we may miss cardinality changes |
|
73 # in the same transaction |
|
74 for rdef in self.reverse_relation_type: |
|
75 card = rdef.cardinality[0] |
|
76 if not card in '?1': |
|
77 qname = role_name('inlined', 'subject') |
|
78 rtype = self.name |
|
79 stype = rdef.stype |
|
80 otype = rdef.otype |
|
81 msg = self._cw._("can't set inlined=True, " |
|
82 "%(stype)s %(rtype)s %(otype)s " |
|
83 "has cardinality=%(card)s") |
|
84 raise ValidationError(self.eid, {qname: msg % locals()}) |
|
85 |
|
86 |
|
87 class CWRelation(AnyEntity): |
|
88 __regid__ = 'CWRelation' |
|
89 fetch_attrs = fetch_config(['cardinality'])[0] |
|
90 |
|
91 def dc_title(self): |
|
92 return u'%s %s %s' % ( |
|
93 self.from_entity[0].name, |
|
94 self.relation_type[0].name, |
|
95 self.to_entity[0].name) |
|
96 |
|
97 def dc_long_title(self): |
|
98 card = self.cardinality |
|
99 scard, ocard = u'', u'' |
|
100 if card[0] != '1': |
|
101 scard = '[%s]' % card[0] |
|
102 if card[1] != '1': |
|
103 ocard = '[%s]' % card[1] |
|
104 return u'%s %s%s%s %s' % ( |
|
105 self.from_entity[0].name, |
|
106 scard, self.relation_type[0].name, ocard, |
|
107 self.to_entity[0].name) |
|
108 |
|
109 @property |
|
110 def rtype(self): |
|
111 return self.relation_type[0] |
|
112 |
|
113 @property |
|
114 def stype(self): |
|
115 return self.from_entity[0] |
|
116 |
|
117 @property |
|
118 def otype(self): |
|
119 return self.to_entity[0] |
|
120 |
|
121 def yams_schema(self): |
|
122 rschema = self._cw.vreg.schema.rschema(self.rtype.name) |
|
123 return rschema.rdefs[(self.stype.name, self.otype.name)] |
|
124 |
|
125 |
|
126 class CWAttribute(CWRelation): |
|
127 __regid__ = 'CWAttribute' |
|
128 |
|
129 def dc_long_title(self): |
|
130 card = self.cardinality |
|
131 scard = u'' |
|
132 if card[0] == '1': |
|
133 scard = '+' |
|
134 return u'%s %s%s %s' % ( |
|
135 self.from_entity[0].name, |
|
136 scard, self.relation_type[0].name, |
|
137 self.to_entity[0].name) |
|
138 |
|
139 |
|
140 class CWConstraint(AnyEntity): |
|
141 __regid__ = 'CWConstraint' |
|
142 fetch_attrs, cw_fetch_order = fetch_config(['value']) |
|
143 |
|
144 def dc_title(self): |
|
145 return '%s(%s)' % (self.cstrtype[0].name, self.value or u'') |
|
146 |
|
147 @property |
|
148 def type(self): |
|
149 return self.cstrtype[0].name |
|
150 |
|
151 |
|
152 class RQLExpression(AnyEntity): |
|
153 __regid__ = 'RQLExpression' |
|
154 fetch_attrs, cw_fetch_order = fetch_config(['exprtype', 'mainvars', 'expression']) |
|
155 |
|
156 def dc_title(self): |
|
157 return self.expression or u'' |
|
158 |
|
159 def dc_long_title(self): |
|
160 return '%s(%s)' % (self.exprtype, self.expression or u'') |
|
161 |
|
162 @property |
|
163 def expression_of(self): |
|
164 for rel in ('read_permission', 'add_permission', 'delete_permission', |
|
165 'update_permission', 'condition'): |
|
166 values = getattr(self, 'reverse_%s' % rel) |
|
167 if values: |
|
168 return values[0] |
|
169 |
|
170 @cached |
|
171 def _rqlexpr(self): |
|
172 if self.exprtype == 'ERQLExpression': |
|
173 return ERQLExpression(self.expression, self.mainvars, self.eid) |
|
174 #if self.exprtype == 'RRQLExpression': |
|
175 return RRQLExpression(self.expression, self.mainvars, self.eid) |
|
176 |
|
177 def check_expression(self, *args, **kwargs): |
|
178 return self._rqlexpr().check(*args, **kwargs) |
|