Bläddra i källkod

Merge branch 'migration_handler':

Add the possibility to change the migartion handler of a Model
It will send changes one by one to the new migartion handler
so it can re-create the Editorial Model
ArnAud 9 år sedan
förälder
incheckning
6388eb6701
4 ändrade filer med 168 tillägg och 134 borttagningar
  1. 17
    0
      EditorialModel/backend/dummy_backend.py
  2. 42
    5
      EditorialModel/model.py
  3. 4
    4
      EditorialModel/test/me.json
  4. 105
    125
      EditorialModel/types.py

+ 17
- 0
EditorialModel/backend/dummy_backend.py Visa fil

@@ -0,0 +1,17 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+## @package EditorialModel.backend.dummy_backend
4
+# @brief Gives an empty backend
5
+#
6
+# Allows an editorial model to use an empty backend
7
+# Mostly for migration and test purpose
8
+
9
+## Manages a Json file based backend structure
10
+class EmBackendDummy(object):
11
+
12
+    def load(self):
13
+        data = {}
14
+        return data
15
+
16
+    def save(self):
17
+        return True

+ 42
- 5
EditorialModel/model.py Visa fil

@@ -4,6 +4,7 @@
4 4
 # Manage instance of an editorial model
5 5
 
6 6
 from EditorialModel.migrationhandler.dummy import DummyMigrationHandler
7
+from EditorialModel.backend.dummy_backend import EmBackendDummy
7 8
 from EditorialModel.classes import EmClass
8 9
 from EditorialModel.fieldgroups import EmFieldGroup
9 10
 from EditorialModel.fields import EmField
@@ -15,7 +16,7 @@ import hashlib
15 16
 ## Manages the Editorial Model
16 17
 class Model(object):
17 18
 
18
-    components_class = [EmClass, EmField, EmFieldGroup, EmType]
19
+    components_class = [EmClass, EmType, EmFieldGroup, EmField]
19 20
 
20 21
     ## Constructor
21 22
     #
@@ -129,7 +130,7 @@ class Model(object):
129 130
     # @param datas dict : the options needed by the component creation
130 131
     # @throw ValueError if datas['rank'] is not valid (too big or too small, not an integer nor 'last' or 'first' )
131 132
     # @todo Handle a raise from the migration handler
132
-    def create_component(self, component_type, datas):
133
+    def create_component(self, component_type, datas, uid=None):
133 134
 
134 135
         em_obj = self.emclass_from_name(component_type)
135 136
 
@@ -138,13 +139,13 @@ class Model(object):
138 139
             rank = datas['rank']
139 140
             del datas['rank']
140 141
 
141
-        datas['uid'] = self.new_uid()
142
+        datas['uid'] = uid if uid else self.new_uid()
142 143
         em_component = em_obj(self, **datas)
143 144
 
144
-        em_component.rank = em_component.get_max_rank() + 1 #Inserting last by default
145
+        em_component.rank = em_component.get_max_rank() + 1 #  Inserting last by default
145 146
 
146 147
         self._components['uids'][em_component.uid] = em_component
147
-        self._components[self.name_from_emclass(em_component.__class__)].append(em_component)
148
+        self._components[component_type].append(em_component)
148 149
 
149 150
         if rank != 'last':
150 151
             em_component.set_rank(1 if rank == 'first' else rank)
@@ -193,3 +194,39 @@ class Model(object):
193 194
     ## Returns a list of all the EmClass objects of the model
194 195
     def classes(self):
195 196
         return list(self._components[self.name_from_emclass(EmClass)])
197
+
198
+    ## Use a new migration handler, re-apply all the ME to this handler
199
+    #
200
+    # @param new_mh MigrationHandler: A migration_handler object
201
+    # @warning : if a relational-attribute field (with 'rel_field_id') comes before it's relational field (with 'rel_to_type_id'), this will blow up
202
+    def migrate_handler(self, new_mh):
203
+        new_me = Model(EmBackendDummy(), new_mh)
204
+        relations = {'fields_list': [], 'superiors_list': []}
205
+
206
+        # re-create component one by one, in components_class[] order
207
+        for cls in self.components_class:
208
+            for component in self.components(cls):
209
+                component_type = self.name_from_emclass(cls)
210
+                component_dump = component.attr_dump
211
+                del component_dump['model'], component_dump['_inited']
212
+                # Save relations between component to apply them later
213
+                for relation in relations.keys():
214
+                    if relation in component_dump and component_dump[relation]:
215
+                        relations[relation].append((component.uid, component_dump[relation]))
216
+                        del component_dump[relation]
217
+                new_me.create_component(component_type, component_dump, component.uid)
218
+
219
+        # apply selected field  to types
220
+        for fields_list in relations['fields_list']:
221
+            uid, fields = fields_list
222
+            for field_id in fields:
223
+                new_me.component(uid).select_field(new_me.component(field_id))
224
+
225
+        # add superiors to types
226
+        # TODO: debug, this add a superior to all types !
227
+        for superiors_list in relations['superiors_list']:
228
+            uid, sup_list = superiors_list
229
+            for nature, superior_uid in sup_list.items():
230
+                new_me.component(uid).add_superior(new_me.component(superior_uid), nature)
231
+
232
+        self.migration_handler = new_mh

+ 4
- 4
EditorialModel/test/me.json Visa fil

@@ -12,7 +12,7 @@
12 12
     "component":"EmField", "name":"titre", "string":"{\"fre\":\"Titre\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "fieldtype":"varchar", "fieldgroup_id":"3", "rel_to_type_id":"", "rel_field_id":"", "optional":0, "internal":"", "icon":"0"
13 13
   },
14 14
   "5" : {
15
-    "component":"EmType", "name":"article", "string":"{\"fre\":\"Article\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"1", "icon":"0", "sortcolumn":"rank", "fields_list":[7]
15
+    "component":"EmType", "name":"article", "string":"{\"fre\":\"Article\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"1", "icon":"0", "sortcolumn":"rank", "fields_list":[7], "superiors_list":{"parent":14}
16 16
   },
17 17
   "6" : {
18 18
     "component":"EmType", "name":"personne", "string":"{\"fre\":\"Personne\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"2", "icon":"0", "sortcolumn":"rank", "fields_list":[10]
@@ -30,16 +30,16 @@
30 30
     "component":"EmField", "name":"prenom", "string":"{\"fre\":\"Preom\"}", "help_text":"{}", "rank":"2", "date_update":"", "date_create":"", "fieldtype":"varchar", "fieldgroup_id":"8", "rel_to_type_id":"", "rel_field_id":"", "optional":1, "internal":"", "icon":"0"
31 31
   },
32 32
   "11" : {
33
-    "component":"EmField", "name":"auteur", "string":"{\"fre\":\"Auteur\"}", "help_text":"{}", "rank":"3", "date_update":"", "date_create":"", "fieldtype":"varchar", "fieldgroup_id":"17", "rel_to_type_id":"6", "rel_field_id":"", "optional":1, "internal":"", "icon":"0"
33
+    "component":"EmField", "name":"auteur", "string":"{\"fre\":\"Auteur\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "fieldtype":"varchar", "fieldgroup_id":"17", "rel_to_type_id":"6", "rel_field_id":"", "optional":1, "internal":"", "icon":"0"
34 34
   },
35 35
   "12" : {
36
-    "component":"EmField", "name":"adresse", "string":"{\"fre\":\"Adresse\"}", "help_text":"{}", "rank":"4", "date_update":"", "date_create":"", "fieldtype":"varchar", "fieldgroup_id":"17", "rel_to_type_id":"", "rel_field_id":"11", "optional":0, "internal":"", "icon":"0"
36
+    "component":"EmField", "name":"adresse", "string":"{\"fre\":\"Adresse\"}", "help_text":"{}", "rank":"2", "date_update":"", "date_create":"", "fieldtype":"varchar", "fieldgroup_id":"17", "rel_to_type_id":"", "rel_field_id":"11", "optional":0, "internal":"", "icon":"0"
37 37
   },
38 38
   "13" : {
39 39
     "component":"EmClass", "name":"publication", "string":"{\"fre\":\"Publication\"}", "help_text":"{}", "rank":"2", "date_update":"", "date_create":"", "classtype":"entity", "icon":"0", "sortcolumn":"rank"
40 40
   },
41 41
   "14" : {
42
-    "component":"EmType", "name":"rubrique", "string":"{\"fre\":\"Rubrique\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"13", "icon":"0", "sortcolumn":"rank", "subordinates_list":{"parent":[5,14]}
42
+    "component":"EmType", "name":"rubrique", "string":"{\"fre\":\"Rubrique\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"13", "icon":"0", "sortcolumn":"rank", "superiors_list":{"parent":14}
43 43
   },
44 44
   "15" : {
45 45
     "component":"EmFieldGroup", "name":"info", "string":"{\"fre\":\"Info\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"13"

+ 105
- 125
EditorialModel/types.py Visa fil

@@ -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():
@@ -110,52 +109,61 @@ class EmType(EmComponent):
110 109
     # Indicates that an optional field is used
111 110
     #
112 111
     # @param field EmField: The optional field to select
113
-    # @return True if success False if failed
114 112
     #
115 113
     # @throw TypeError if field is not an EmField instance
116 114
     # @throw ValueError if field is not optional or is not associated with this type
117
-    # @see EmType::_opt_field_act()
115
+    # @throw MigrationHandlerChangeError if migration handler is not happy with the change
116
+    # @see EmType::_change_field_list()
118 117
     def select_field(self, field):
119 118
         if field.uid in self.fields_list:
120 119
             return True
121
-        return self._change_field_list(field, True)
120
+        self._change_field_list(field, True)
122 121
 
123 122
     ## Unselect_field (Function)
124 123
     #
125 124
     # Indicates that an optional field will not be used
126 125
     #
127 126
     # @param field EmField: The optional field to unselect
128
-    # @return True if success False if fails
129 127
     #
130 128
     # @throw TypeError if field is not an EmField instance
131 129
     # @throw ValueError if field is not optional or is not associated with this type
132
-    # @see EmType::_opt_field_act()
130
+    # @throw MigrationHandlerChangeError if migration handler is not happy with the change
131
+    # @see EmType::_change_field_list()
133 132
     def unselect_field(self, field):
134 133
         if field.uid not in self.fields_list:
135 134
             return True
136
-        return self._change_field_list(field, False)
135
+        self._change_field_list(field, False)
137 136
 
138 137
     ## @brief Select or unselect an optional field
139 138
     # @param field EmField: The EmField to select or unselect
140 139
     # @param select bool: If True select field, else unselect it
141
-    # @return True if success False if fails
142 140
     #
143 141
     # @throw TypeError if field is not an EmField instance
144 142
     # @throw ValueError if field is not optional or is not associated with this type
145
-    def _change_field_list(self, field, add=True):  # TODO voir si on conserve l'argument "select"
143
+    # @throw MigrationHandlerChangeError if migration handler is not happy with the change
144
+    def _change_field_list(self, field, select=True):
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
 
153
-        if add:
154
-            self.fields_list.append(field.uid)
155
-        else:
156
-            self.fields_list.remove(field.uid)
157
-
158
-        return True
152
+        try:
153
+            if select:
154
+                self.fields_list.append(field.uid)
155
+                self.model.migration_handler.register_change(self.model, self.uid, None, {'fields_list': field.uid})
156
+            else:
157
+                self.fields_list.remove(field.uid)
158
+                self.model.migration_handler.register_change(self.model, self.uid, {'fields_list': field.uid}, None)
159
+        except MigrationHandlerChangeError as exception_object:
160
+            if select:
161
+                self.fields_list.remove(field.uid)
162
+            else:
163
+                self.fields_list.append(field.uid)
164
+            raise exception_object
165
+
166
+        self.model.migration_handler.register_model_state(self.model, hash(self.model))
159 167
 
160 168
     ## Get the list of associated hooks
161 169
     # @note Not conceptualized yet
@@ -186,22 +194,22 @@ class EmType(EmComponent):
186 194
     # EmType instance
187 195
     # @throw RuntimeError if a nature fetched from db is not valid
188 196
     def subordinates(self):
189
-        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
190 206
 
191 207
     ## @brief Get the list of superiors by relation's nature
192 208
     # Get a list of EmType that are superiors of this type
193 209
     # @return Return a dict with relation nature as keys and an EmType as value
194 210
     # @throw RuntimeError if a nature has multiple superiors
195 211
     def superiors(self):
196
-        superiors = {}
197
-        for em_type in self.model.components(EmType):
198
-            for nature, sub_uids in em_type.subordinates_list.items():
199
-                if self.uid in sub_uids:
200
-                    if nature in superiors:
201
-                        raise RuntimeError("Multiple superiors found for relation of nature '%s' for EmType %d"%(nature, self.uid))
202
-                    else:
203
-                        superiors[nature] = em_type
204
-        return superiors
212
+        return { nature:self.model.component(superior_uid) for nature, superior_uid in self.superiors_list.items() }
205 213
 
206 214
     ## Add a superior in the type hierarchy
207 215
     # @param em_type EmType: An EmType instance
@@ -212,11 +220,6 @@ class EmType(EmComponent):
212 220
     # @throw ValueError when relation_nature isn't reconized or not allowed for this type
213 221
     # @throw ValueError when relation_nature don't allow to link this types together
214 222
     def add_superior(self, em_type, relation_nature):
215
-        if not isinstance(em_type, EmType) or not isinstance(relation_nature, str):
216
-            raise TypeError("Excepted <class EmType> and <class str> as em_type argument. But got : " + str(type(em_type)) + " " + str(type(relation_nature)))
217
-        if relation_nature not in EmClassType.natures(self.classtype['name']):
218
-            raise ValueError("Invalid nature for add_superior : '" + relation_nature + "'. Allowed relations for this type are " + str(EmClassType.natures(self.classtype['name'])))
219
-
220 223
         #Checking that this relation is allowed by the nature of the relation
221 224
         att = self.classtype['hierarchy'][relation_nature]['attach']
222 225
         if att == 'classtype':
@@ -225,65 +228,44 @@ class EmType(EmComponent):
225 228
         elif self.name != em_type.name:
226 229
             raise ValueError("Not allowed to put a different em_type as superior in a relation of nature '" + relation_nature + "'")
227 230
 
228
-        # TODO Réimplémenter
229
-        # conn = self.db_engine.connect()
230
-        # htable = self._table_hierarchy
231
-        # values = {'subordinate_id': self.uid, 'superior_id': em_type.uid, 'nature': relation_nature}
232
-        # req = htable.insert(values=values)
233
-        #
234
-        # try:
235
-        #     conn.execute(req)
236
-        # except sql.exc.IntegrityError:
237
-        #     ret = False
238
-        # else:
239
-        #     ret = True
240
-        # finally:
241
-        #     conn.close()
242
-        #
243
-        # return ret
231
+        self._change_superiors_list(em_type, relation_nature, True)
244 232
 
245 233
     ## Delete a superior in the type hierarchy
246 234
     # @param em_type EmType: An EmType instance
235
+    # @param relation_nature str: The name of the relation's nature
247 236
     # @throw TypeError when em_type isn't an EmType instance
237
+    # @throw ValueError when relation_nature isn't reconized or not allowed for this type
248 238
     def del_superior(self, em_type, relation_nature):
249
-        if not isinstance(em_type, EmType):
250
-            raise TypeError("Excepted <class EmType> as argument. But got : " + str(type(em_type)))
239
+        self._change_superiors_list(em_type, relation_nature, False)
240
+
241
+    ## Apply changes to the superiors_list
242
+    # @param em_type EmType: An EmType instance
243
+    # @param relation_nature str: The name of the relation's nature
244
+    # @param add bool: Add or delete relation
245
+    def _change_superiors_list(self, em_type, relation_nature, add=True):
246
+        # check instance of parameters
247
+        if not isinstance(em_type, EmType) or not isinstance(relation_nature, str):
248
+            raise TypeError("Excepted <class EmType> and <class str> as em_type argument. But got : " + str(type(em_type)) + " " + str(type(relation_nature)))
249
+        # check if relation_nature is valid for this type
251 250
         if relation_nature not in EmClassType.natures(self.classtype['name']):
252 251
             raise ValueError("Invalid nature for add_superior : '" + relation_nature + "'. Allowed relations for this type are " + str(EmClassType.natures(self.classtype['name'])))
253 252
 
254
-        # TODO Réimplémenter
255
-        # conn = self.db_engine.connect()
256
-        # htable = self._table_hierarchy
257
-        # req = htable.delete(htable.c.superior_id == em_type.uid and htable.c.nature == relation_nature)
258
-        # conn.execute(req)
259
-        # conn.close()
260
-
261
-    ## @brief Get the list of linked type
262
-    # Types are linked with special fields called relation_to_type fields
263
-    # @return a list of EmType
264
-    # @see EmFields
265
-    def linked_types(self):
266
-        return self._linked_types_db()  # TODO changer l'appel
267
-
268
-    ## @brief Return the list of all the types linked to this type, should they be superiors or subordinates
269
-    # @return A list of EmType objects
270
-    # def _linked_types_db(self):
271
-    #     conn = self.db_engine.connect()
272
-    #     htable = self._table_hierarchy
273
-    #     req = htable.select(htable.c.superior_id, htable.c.subordinate_id)
274
-    #     req = req.where(sql.or_(htable.c.subordinate_id == self.uid, htable.c.superior_id == self.uid))
275
-    #
276
-    #     res = conn.execute(req)
277
-    #     rows = res.fetchall()
278
-    #     conn.close()
279
-    #
280
-    #     rows = dict(zip(rows.keys(), rows))
281
-    #     result = []
282
-    #     for row in rows:
283
-    #         result.append(EmType(row['subordinate_id'] if row['superior_id'] == self.uid else row['superior_id']))
284
-    #
285
-    #     return result
286
-    
253
+        try:
254
+            if add:
255
+                self.superiors_list[relation_nature] = em_type.uid
256
+                self.model.migration_handler.register_change(self.model, self.uid, None, {'superiors_list': {relation_nature: em_type.uid}})
257
+            else:
258
+                del self.superiors_list[relation_nature]
259
+                self.model.migration_handler.register_change(self.model, self.uid, {'superiors_list': {relation_nature: em_type.uid}}, None)
260
+        except MigrationHandlerChangeError as exception_object:
261
+            if add:
262
+                del self.superiors_list[relation_nature]
263
+            else:
264
+                self.superiors_list[relation_nature] = em_type.uid
265
+            raise exception_object
266
+
267
+        self.model.migration_handler.register_model_state(self.model, hash(self.model))
268
+
287 269
     ## Checks if the EmType is valid
288 270
     # @throw EmComponentCheckError if check fails
289 271
     def check(self):
@@ -293,52 +275,50 @@ class EmType(EmComponent):
293 275
             raise EmComponentCheckError("class_id contains an uid that does not exists '%d'" % self.class_id)
294 276
         if not isinstance(em_class, EditorialModel.classes.EmClass):
295 277
             raise EmComponentCheckError("class_id contains an uid from a component that is not an EmClass but a %s" % str(type(emc_class)))
296
-        
297
-        for i,fuid in enumerate(self.fields_list):
298
-            field = self.model.component(fuid)
278
+
279
+        for i,f_uid in enumerate(self.fields_list):
280
+            field = self.model.component(f_uid)
299 281
             if not field:
300
-                raise EmComponentCheckError("The element %d of selected_field is a non existing uid '%d'"%(i, fuid))
282
+                raise EmComponentCheckError("The element %d of selected_field is a non existing uid '%d'"%(i, f_uid))
301 283
             if not isinstance(field, EmField):
302 284
                 raise EmComponentCheckError("The element %d of selected_field is not an EmField but a %s" % (i, str(type(field)) ))
303 285
             if not field.optional:
304 286
                 raise EmComponentCheckError("The element %d of selected_field is an EmField not optional"  % i )
305 287
             if field.fieldgroup_id not in [ fg.uid for fg in self.fieldgroups() ]:
306 288
                 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)
307
-        for nature in self.subordinates_list:
308
-            for i, tuid in enumerate(self.subordinates_list[nature]):
309
-                em_type = self.model.component(tuid)
310
-                if not em_type:
311
-                    raise EmComponentCheckError("The element %d of subordinates contains a non existing uid '%d'" % (i, tuid))
312
-                if not isinstance(em_type, EmType):
313
-                    raise EmComponentCheckError("The element %d of subordinates contains a component that is not an EmType but a %s" % (i, str(type(em_type))))
314
-                if nature not in EmClassType.natures(self.em_class.classtype):
315
-                    raise EmComponentCheckError("The relation nature '%s' of the element %d of subordinates is not valid for this EmType classtype '%s'", (nature, i, self.classtype) )
316
-    
317
-                nat_spec = getattr(EmClassType, self.em_class.classtype)['hierarchy'][nature]
318
-    
319
-                if nat_spec['attach'] == 'classtype':
320
-                    if self.classtype != em_type.classtype:
321
-                        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) )
322
-                elif nat_spec['attach'] == 'type':
323
-                    if self.uid != em_type.uid:
324
-                        raise EmComponentCheckError("The element %d of subordinates is a different EmType. But the relation nature '%s' require the same EmType" % (i, nature))
289
+
290
+        for nature, sup_uid in self.superiors_list.items():
291
+            em_type = self.model.component(sup_uid)
292
+            if not em_type:
293
+                raise EmComponentCheckError("The superior is a non existing uid '%d'" % (sup_uid))
294
+            if not isinstance(em_type, EmType):
295
+                raise EmComponentCheckError("The superior is a component that is not an EmType but a %s" % (str(type(em_type))))
296
+            if nature not in EmClassType.natures(self.em_class.classtype):
297
+                raise EmComponentCheckError("The relation nature '%s' of the superior is not valid for this EmType classtype '%s'", (nature, self.classtype) )
298
+
299
+            nat_spec = getattr(EmClassType, self.em_class.classtype)['hierarchy'][nature]
300
+
301
+            if nat_spec['attach'] == 'classtype':
302
+                if self.classtype != em_type.classtype:
303
+                    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) )
304
+            elif nat_spec['attach'] == 'type':
305
+                if self.uid != em_type.uid:
306
+                    raise EmComponentCheckError("The superior is a different EmType. But the relation nature '%s' require the same EmType" % (nature))
307
+            else:
308
+                raise NotImplementedError("The nature['attach'] '%s' is not implemented in this check !" % nat_spec['attach'])
309
+
310
+            if 'max_depth' in nat_spec and nat_spec['max_depth'] > 0:
311
+                depth = 1
312
+                cur_type = em_type
313
+                while depth >= nat_spec['max_depth']:
314
+                    depth +=1
315
+                    if len(cur_type.subordinates()[nature]) == 0:
316
+                        break
325 317
                 else:
326
-                    raise NotImplementedError("The nature['attach'] '%s' is not implemented in this check !" % nat_spec['attach'])
327
-    
328
-                if 'max_depth' in nat_spec and nat_spec['max_depth'] > 0:
329
-                    depth = 1
330
-                    cur_type = em_type
331
-                    while depth >= nat_spec['max_depth']:
332
-                        depth +=1
333
-                        if len(cur_type.subordinates()[nature]) == 0:
334
-                            break
335
-                    else:
336
-                        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) )
337
-        
318
+                    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) )
319
+
338 320
         for nature in self.subordinates():
339 321
             nat_spec = getattr(EmClassType, self.em_class.classtype)['hierarchy'][nature]
340 322
             if 'max_child' in nat_spec and nat_spec['max_child'] > 0:
341 323
                 if len(self.subordinates()[nature]) > nat_spec['max_child']:
342 324
                     raise EmComponentCheckError("The EmType has more child than allowed in the relation's nature : %d > %d" (len(self.subordinates()[nature], nat_spec['max_child'])))
343
-        #pass
344
-

Loading…
Avbryt
Spara