|
@@ -25,7 +25,7 @@ class EmType(EmComponent):
|
25
|
25
|
## Instanciate a new EmType
|
26
|
26
|
# @todo define and check types for icon and sortcolumn
|
27
|
27
|
# @todo better check self.subordinates
|
28
|
|
- def __init__(self, model, uid, name, class_id, fields_list = [], subordinates_list = {}, icon = '0', sortcolumn = 'rank', string = None, help_text = None, date_update = None, date_create = None, rank = None):
|
|
28
|
+ def __init__(self, model, uid, name, class_id, fields_list = [], superiors_list = {}, icon = '0', sortcolumn = 'rank', string = None, help_text = None, date_update = None, date_create = None, rank = None):
|
29
|
29
|
self.class_id = class_id
|
30
|
30
|
self.check_type('class_id', int)
|
31
|
31
|
self.fields_list = fields_list
|
|
@@ -34,14 +34,13 @@ class EmType(EmComponent):
|
34
|
34
|
if not isinstance(l_uid, int):
|
35
|
35
|
raise AttributeError("Excepted fields_list to be a list of integers, but found a +"+str(type(l_uid))+" in it")
|
36
|
36
|
|
37
|
|
- self.subordinates_list = subordinates_list
|
38
|
|
- self.check_type('subordinates_list', dict)
|
39
|
|
- for nature, uids in self.subordinates_list.items():
|
|
37
|
+ self.superiors_list = superiors_list
|
|
38
|
+ self.check_type('superiors_list', dict)
|
|
39
|
+ for nature, sup_uid in self.superiors_list.items():
|
40
|
40
|
if nature not in [EmNature.PARENT, EmNature.TRANSLATION, EmNature.IDENTITY]:
|
41
|
41
|
raise AttributeError("Nature '%s' of subordinates is not allowed !" % nature)
|
42
|
|
- for uid in uids:
|
43
|
|
- if not isinstance(uid, int):
|
44
|
|
- raise AttributeError("Excepted subordinates of nature '%s' to be a list int !" % nature)
|
|
42
|
+ if not isinstance(sup_uid, int):
|
|
43
|
+ raise AttributeError("Excepted subordinates of nature '%s' to be an int !" % nature)
|
45
|
44
|
|
46
|
45
|
self.icon = icon
|
47
|
46
|
self.sortcolumn = sortcolumn
|
|
@@ -79,7 +78,7 @@ class EmType(EmComponent):
|
79
|
78
|
# @todo Check if the type is not linked by any EmClass
|
80
|
79
|
# @todo Check if there is no other ''non-deletion'' conditions
|
81
|
80
|
def delete_check(self):
|
82
|
|
- if sum(self.subordinates_list) > 0:
|
|
81
|
+ if len(self.subordinates()) > 0:
|
83
|
82
|
return False
|
84
|
83
|
#Delete all relation with superiors
|
85
|
84
|
for nature, sups in self.superiors().items():
|
|
@@ -146,7 +145,7 @@ class EmType(EmComponent):
|
146
|
145
|
if not isinstance(field, EmField):
|
147
|
146
|
raise TypeError("Excepted <class EmField> as field argument. But got " + str(type(field)))
|
148
|
147
|
if not field in self.em_class.fields():
|
149
|
|
- raise ValueError("This field is not part of this type")
|
|
148
|
+ raise ValueError("This field " + str(field) + "is not part of the type " + str(self))
|
150
|
149
|
if not field.optional:
|
151
|
150
|
raise ValueError("This field is not optional")
|
152
|
151
|
|
|
@@ -195,22 +194,22 @@ class EmType(EmComponent):
|
195
|
194
|
# EmType instance
|
196
|
195
|
# @throw RuntimeError if a nature fetched from db is not valid
|
197
|
196
|
def subordinates(self):
|
198
|
|
- return { nature: [ self.model.component(tuid) for tuid in self.subordinates_list[nature] ] for nature in self.subordinates_list }
|
|
197
|
+ subordinates = {}
|
|
198
|
+ for em_type in self.model.components(EmType):
|
|
199
|
+ for nature, superior_uid in em_type.superiors_list.items():
|
|
200
|
+ if self.uid == superior_uid:
|
|
201
|
+ if nature in subordinates:
|
|
202
|
+ subordinates[nature].append(em_type)
|
|
203
|
+ else:
|
|
204
|
+ subordinates[nature] = [em_type]
|
|
205
|
+ return subordinates
|
199
|
206
|
|
200
|
207
|
## @brief Get the list of superiors by relation's nature
|
201
|
208
|
# Get a list of EmType that are superiors of this type
|
202
|
209
|
# @return Return a dict with relation nature as keys and an EmType as value
|
203
|
210
|
# @throw RuntimeError if a nature has multiple superiors
|
204
|
211
|
def superiors(self):
|
205
|
|
- superiors = {}
|
206
|
|
- for em_type in self.model.components(EmType):
|
207
|
|
- for nature, sub_uids in em_type.subordinates_list.items():
|
208
|
|
- if self.uid in sub_uids:
|
209
|
|
- if nature in superiors:
|
210
|
|
- raise RuntimeError("Multiple superiors found for relation of nature '%s' for EmType %d"%(nature, self.uid))
|
211
|
|
- else:
|
212
|
|
- superiors[nature] = em_type
|
213
|
|
- return superiors
|
|
212
|
+ return { nature:self.model.component(superior_uid) for nature, superior_uid in self.superiors_list.items() }
|
214
|
213
|
|
215
|
214
|
## Add a superior in the type hierarchy
|
216
|
215
|
# @param em_type EmType: An EmType instance
|
|
@@ -292,7 +291,7 @@ class EmType(EmComponent):
|
292
|
291
|
# result.append(EmType(row['subordinate_id'] if row['superior_id'] == self.uid else row['superior_id']))
|
293
|
292
|
#
|
294
|
293
|
# return result
|
295
|
|
-
|
|
294
|
+
|
296
|
295
|
## Checks if the EmType is valid
|
297
|
296
|
# @throw EmComponentCheckError if check fails
|
298
|
297
|
def check(self):
|
|
@@ -302,52 +301,50 @@ class EmType(EmComponent):
|
302
|
301
|
raise EmComponentCheckError("class_id contains an uid that does not exists '%d'" % self.class_id)
|
303
|
302
|
if not isinstance(em_class, EditorialModel.classes.EmClass):
|
304
|
303
|
raise EmComponentCheckError("class_id contains an uid from a component that is not an EmClass but a %s" % str(type(emc_class)))
|
305
|
|
-
|
306
|
|
- for i,fuid in enumerate(self.fields_list):
|
307
|
|
- field = self.model.component(fuid)
|
|
304
|
+
|
|
305
|
+ for i,f_uid in enumerate(self.fields_list):
|
|
306
|
+ field = self.model.component(f_uid)
|
308
|
307
|
if not field:
|
309
|
|
- raise EmComponentCheckError("The element %d of selected_field is a non existing uid '%d'"%(i, fuid))
|
|
308
|
+ raise EmComponentCheckError("The element %d of selected_field is a non existing uid '%d'"%(i, f_uid))
|
310
|
309
|
if not isinstance(field, EmField):
|
311
|
310
|
raise EmComponentCheckError("The element %d of selected_field is not an EmField but a %s" % (i, str(type(field)) ))
|
312
|
311
|
if not field.optional:
|
313
|
312
|
raise EmComponentCheckError("The element %d of selected_field is an EmField not optional" % i )
|
314
|
313
|
if field.fieldgroup_id not in [ fg.uid for fg in self.fieldgroups() ]:
|
315
|
314
|
raise EmComponentCheckErrro("The element %d of selected_field is an EmField that is part of an EmFieldGroup that is not associated with this EmType" % i)
|
316
|
|
- for nature in self.subordinates_list:
|
317
|
|
- for i, tuid in enumerate(self.subordinates_list[nature]):
|
318
|
|
- em_type = self.model.component(tuid)
|
319
|
|
- if not em_type:
|
320
|
|
- raise EmComponentCheckError("The element %d of subordinates contains a non existing uid '%d'" % (i, tuid))
|
321
|
|
- if not isinstance(em_type, EmType):
|
322
|
|
- raise EmComponentCheckError("The element %d of subordinates contains a component that is not an EmType but a %s" % (i, str(type(em_type))))
|
323
|
|
- if nature not in EmClassType.natures(self.em_class.classtype):
|
324
|
|
- raise EmComponentCheckError("The relation nature '%s' of the element %d of subordinates is not valid for this EmType classtype '%s'", (nature, i, self.classtype) )
|
325
|
|
-
|
326
|
|
- nat_spec = getattr(EmClassType, self.em_class.classtype)['hierarchy'][nature]
|
327
|
|
-
|
328
|
|
- if nat_spec['attach'] == 'classtype':
|
329
|
|
- if self.classtype != em_type.classtype:
|
330
|
|
- raise EmComponentCheckError("The element %d of subordinates is of '%s' classtype. But the current type is of '%s' classtype, and relation nature '%s' require two EmType of same classtype" % (i, em_type.classtype, self.classtype, nature) )
|
331
|
|
- elif nat_spec['attach'] == 'type':
|
332
|
|
- if self.uid != em_type.uid:
|
333
|
|
- raise EmComponentCheckError("The element %d of subordinates is a different EmType. But the relation nature '%s' require the same EmType" % (i, nature))
|
|
315
|
+
|
|
316
|
+ for nature, sup_uid in self.superiors_list.items():
|
|
317
|
+ em_type = self.model.component(sup_uid)
|
|
318
|
+ if not em_type:
|
|
319
|
+ raise EmComponentCheckError("The superior is a non existing uid '%d'" % (sup_uid))
|
|
320
|
+ if not isinstance(em_type, EmType):
|
|
321
|
+ raise EmComponentCheckError("The superior is a component that is not an EmType but a %s" % (str(type(em_type))))
|
|
322
|
+ if nature not in EmClassType.natures(self.em_class.classtype):
|
|
323
|
+ raise EmComponentCheckError("The relation nature '%s' of the superior is not valid for this EmType classtype '%s'", (nature, self.classtype) )
|
|
324
|
+
|
|
325
|
+ nat_spec = getattr(EmClassType, self.em_class.classtype)['hierarchy'][nature]
|
|
326
|
+
|
|
327
|
+ if nat_spec['attach'] == 'classtype':
|
|
328
|
+ if self.classtype != em_type.classtype:
|
|
329
|
+ raise EmComponentCheckError("The superior is of '%s' classtype. But the current type is of '%s' classtype, and relation nature '%s' require two EmType of same classtype" % (em_type.classtype, self.classtype, nature) )
|
|
330
|
+ elif nat_spec['attach'] == 'type':
|
|
331
|
+ if self.uid != em_type.uid:
|
|
332
|
+ raise EmComponentCheckError("The superior is a different EmType. But the relation nature '%s' require the same EmType" % (nature))
|
|
333
|
+ else:
|
|
334
|
+ raise NotImplementedError("The nature['attach'] '%s' is not implemented in this check !" % nat_spec['attach'])
|
|
335
|
+
|
|
336
|
+ if 'max_depth' in nat_spec and nat_spec['max_depth'] > 0:
|
|
337
|
+ depth = 1
|
|
338
|
+ cur_type = em_type
|
|
339
|
+ while depth >= nat_spec['max_depth']:
|
|
340
|
+ depth +=1
|
|
341
|
+ if len(cur_type.subordinates()[nature]) == 0:
|
|
342
|
+ break
|
334
|
343
|
else:
|
335
|
|
- raise NotImplementedError("The nature['attach'] '%s' is not implemented in this check !" % nat_spec['attach'])
|
336
|
|
-
|
337
|
|
- if 'max_depth' in nat_spec and nat_spec['max_depth'] > 0:
|
338
|
|
- depth = 1
|
339
|
|
- cur_type = em_type
|
340
|
|
- while depth >= nat_spec['max_depth']:
|
341
|
|
- depth +=1
|
342
|
|
- if len(cur_type.subordinates()[nature]) == 0:
|
343
|
|
- break
|
344
|
|
- else:
|
345
|
|
- raise EmComponentCheckError("The relation with the element %d of subordinates has a depth superior than the maximum depth ( %d ) allowed by the relation's nature ( '%s' )" %( i, nat_spec['max_depth'], nature) )
|
346
|
|
-
|
|
344
|
+ raise EmComponentCheckError("The relation with the element %d of subordinates has a depth superior than the maximum depth ( %d ) allowed by the relation's nature ( '%s' )" %( i, nat_spec['max_depth'], nature) )
|
|
345
|
+
|
347
|
346
|
for nature in self.subordinates():
|
348
|
347
|
nat_spec = getattr(EmClassType, self.em_class.classtype)['hierarchy'][nature]
|
349
|
348
|
if 'max_child' in nat_spec and nat_spec['max_child'] > 0:
|
350
|
349
|
if len(self.subordinates()[nature]) > nat_spec['max_child']:
|
351
|
350
|
raise EmComponentCheckError("The EmType has more child than allowed in the relation's nature : %d > %d" (len(self.subordinates()[nature], nat_spec['max_child'])))
|
352
|
|
- #pass
|
353
|
|
-
|