1 # CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
19 # ======================================================================
25 from Noyau.N_MCLIST import MCList
26 from Noyau.N_MCSIMP import MCSIMP
27 from Noyau.N_MCFACT import MCFACT
28 from Noyau.N_MCBLOC import MCBLOC
31 class MCCOMPO(I_OBJECT.OBJECT):
32 def getlabeltext(self):
34 Retourne le label de self suivant qu'il s'agit d'un MCFACT,
35 d'un MCBLOC ou d'un MCFACT appartenant à une MCList :
36 utilisée pour l'affichage dans l'arbre
38 objet = self.parent.get_child(self.nom)
39 # objet peut-être self ou une MCList qui contient self ...
40 if isinstance(objet,MCList) :
41 index = objet.get_index(self)+1 # + 1 à cause de la numérotation qui commence à 0
42 label = self.nom +'_'+`index`+':'
47 def get_liste_mc_ordonnee(self,liste,dico):
49 Retourne la liste ordonnée (suivant le catalogue) des mots-clés
50 d'une entité composée dont le chemin complet est donné sous forme
51 d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
52 il faut encore réarranger cette liste (certains mots-clés déjà
53 présents ne doivent plus être proposés, règles ...)
55 return self.filtre_liste_mc(self.get_liste_mc_ordonnee_brute(liste,dico))
57 def get_liste_mc_ordonnee_brute(self,liste,dico):
59 Retourne la liste ordonnée (suivant le catalogue) BRUTE des mots-clés
60 d'une entité composée dont le chemin complet est donné sous forme
61 d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
64 objet_cata = dico[arg]
65 dico=objet_cata.entites
66 return objet_cata.ordre_mc
68 def filtre_liste_mc(self,liste_brute):
70 Cette méthode est appelée par EFICAS afin de présenter à
71 l'utilisateur la liste des enfants possibles de self actualisée
72 en fonction du contexte de self. En clair, sont supprimés de la
73 liste des possibles (fournie par la définition), les mots-clés
74 exclus par les règles de self et les mots-clés ne pouvant plus
77 liste = copy(liste_brute)
78 liste_mc_presents = self.liste_mc_presents()
79 # on enlève les mots-clés non permis par les règles
80 for regle in self.definition.regles:
81 # la méthode purge_liste est à développer pour chaque règle qui
82 # influe sur la liste de choix à proposer à l'utilisateur
83 # --> EXCLUS,UN_PARMI,PRESENT_ABSENT
84 liste = regle.purge_liste(liste,liste_mc_presents)
85 # on enlève les mots-clés dont l'occurrence est déjà atteinte
86 liste_copy = copy(liste)
88 objet = self.get_child(k,restreint = 'oui')
90 # l'objet est déjà présent : il faut distinguer plusieurs cas
91 if isinstance(objet,MCSIMP):
92 # un mot-clé simple ne peut pas être répété
94 elif isinstance(objet,MCBLOC):
95 # un bloc conditionnel ne doit pas apparaître dans la liste de choix
97 elif isinstance(objet,MCFACT):
98 # un mot-clé facteur ne peut pas être répété plus de self.max fois
99 if objet.definition.max == 1:
101 elif isinstance(objet,MCList):
103 nb_occur_maxi = objet[0].definition.max
104 if len(objet) >= nb_occur_maxi:
109 #XXX CCAR : les MCNUPLET ne sont pas traités
110 if CONTEXT.debug : print ' ',k,' est un objet de type inconnu :',type(objet)
112 # l'objet est absent : on enlève de la liste les blocs
113 if self.definition.entites[k].statut=='c' :
115 if self.definition.entites[k].label=='BLOC':
117 # Pour corriger les exces qui pourraient etre commis dans la methode purge_liste
118 # des regles, on essaie de compenser comme suit :
119 # on ajoute les mots cles facteurs presents dont l'occurence n'est pas atteinte
120 for k in liste_mc_presents:
121 if k in liste:continue
122 objet = self.get_child(k,restreint = 'oui')
123 if isinstance(objet,MCFACT):
124 # un mot-clé facteur ne peut pas être répété plus de self.max fois
125 if objet.definition.max > 1:
127 elif isinstance(objet,MCList):
128 nb_occur_maxi = objet[0].definition.max
129 if len(objet) < nb_occur_maxi:
133 def liste_mc_presents(self):
135 Retourne la liste des noms des mots-clés fils de self présents construite
136 à partir de self.mc_liste
139 for v in self.mc_liste:
144 def ordonne_liste_mc(self,liste_mc_a_ordonner,liste_noms_mc_ordonnee):
146 Retourne liste_mc_a_ordonner ordonnée suivant l'ordre
147 donné par liste_noms_mc_ordonnee
150 # on transforme liste_a_ordonner en un dictionnaire (plus facile à consulter)
152 for mc in liste_mc_a_ordonner:
154 # on construit la liste des objets ordonnés
155 for nom_mc in liste_noms_mc_ordonnee:
156 if d_mc.has_key(nom_mc):
157 liste.append(d_mc.get(nom_mc))
161 def suppentite(self,objet) :
163 Supprime le fils 'objet' de self :
164 Retourne 1 si la suppression a pu être effectuée,
165 Retourne 0 dans le cas contraire
168 if not objet in self.mc_liste:
169 # Impossible de supprimer objet. Il n'est pas dans mc_liste
174 if hasattr(objet.definition,'position'):
175 if objet.definition.position == 'global' :
176 self.delete_mc_global(objet)
177 elif objet.definition.position == 'global_jdc' :
178 self.delete_mc_global_jdc(objet)
179 self.mc_liste.remove(objet)
187 return self.definition.statut=='o'
189 def addentite(self,name,pos=None):
191 Ajoute le mot-cle name à la liste des mots-cles de
195 if type(name)==types.StringType :
196 # on est en mode création d'un motcle
197 if self.ispermis(name) == 0 : return 0
198 objet=self.definition.entites[name](val=None,nom=name,parent=self)
199 if hasattr(objet.definition,'position'):
200 if objet.definition.position == 'global' :
201 self.append_mc_global(objet)
202 elif objet.definition.position == 'global_jdc' :
203 self.append_mc_global_jdc(objet)
205 # dans ce cas on est en mode copie d'un motcle
207 objet.verif_existence_sd()
208 # si un objet de même nom est déjà présent dans la liste
209 # et si l'objet est répétable
210 # il faut créer une MCList et remplacer l'objet de la liste
212 test1 = objet.isrepetable()
213 old_obj = self.get_child(objet.nom,restreint = 'oui')
214 test2 = self.ispermis(objet)
215 #print "test1,test2=",test1,test2
216 if test1 == 0 and old_obj :
217 self.jdc.send_message("L'objet %s ne peut pas être répété" %objet.nom)
221 self.jdc.send_message("L'objet %s ne peut être un fils de %s" %(objet.nom,self.nom))
226 #if not isinstance(old_obj,MCList):
227 if not old_obj.isMCList():
228 # un objet de même nom existe déjà mais ce n'est pas une MCList
229 # Il faut en créer une
230 # L'objet existant (old_obj) est certainement un MCFACT
231 # qui pointe vers un constructeur
232 # de MCList : definition.liste_instance
233 #print "un objet de même type existe déjà"
234 index = self.mc_liste.index(old_obj)
235 #XXX remplacé par definition.list_instance : new_obj = MCList()
236 new_obj = old_obj.definition.list_instance()
237 new_obj.init(objet.nom,self)
238 new_obj.append(old_obj)
239 new_obj.append(objet)
240 # Il ne faut pas oublier de reaffecter le parent d'obj
242 self.mc_liste.remove(old_obj)
243 self.mc_liste.insert(index,new_obj)
247 # une liste d'objets de même type existe déjà
248 #print "une liste d'objets de même type existe déjà"
249 old_obj.append(objet)
250 # Il ne faut pas oublier de reaffecter le parent d'obj
255 self.mc_liste.append(objet)
257 self.mc_liste.insert(pos,objet)
258 # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
263 def ispermis(self,fils):
265 Retourne 1 si l'objet de nom nom_fils
266 est bien permis, cad peut bien être un fils de self,
269 if type(fils) == types.StringType :
270 # on veut juste savoir si self peut avoir un fils de nom 'fils'
271 if self.definition.entites.has_key(fils):
275 elif type(fils) == types.InstanceType:
276 # fils est un objet (commande,mcf,mclist)
277 # on est dans le cas d'une tentative de copie de l'objet
278 # on veut savoir si l'objet peut bien être un fils de self :
279 # la vérification du nom de suffit pas (plusieurs commandes
280 # ont le même mot-clé facteur AFFE ... et c'est l'utilisateur
281 # qui choisit le père d'où un risque d'erreur)
282 if not self.definition.entites.has_key(fils.nom):
285 if fils.parent.nom != self.nom : return 0
288 def liste_mc_presents(self):
290 Retourne la liste des noms des mots-clés fils de self présents
291 construite à partir de self.mc_liste
294 for v in self.mc_liste:
299 def delete_concept(self,sd):
304 Mettre a jour les fils de l objet suite à la disparition du
306 Seuls les mots cles simples MCSIMP font un traitement autre que
307 de transmettre aux fils
309 for child in self.mc_liste :
310 child.delete_concept(sd)
312 def delete_mc_global(self,mc):
314 Supprime le mot-clé mc de la liste des mots-clés globaux de l'étape
316 etape = self.get_etape()
319 del etape.mc_globaux[nom]
321 def delete_mc_global_jdc(self,mc):
323 Supprime le mot-clé mc de la liste des mots-clés globaux du jdc
326 del self.jdc.mc_globaux[nom]
329 """ Retourne une copie de self """
330 objet = self.makeobjet()
331 # FR : attention !!! avec makeobjet, objet a le même parent que self
332 # ce qui n'est pas du tout bon dans le cas d'une copie !!!!!!!
333 # FR : peut-on passer par là autrement que dans le cas d'une copie ???
334 # FR --> je suppose que non
335 # XXX CCAR : le pb c'est qu'on vérifie ensuite quel parent avait l'objet
336 # Il me semble preferable de changer le parent a la fin quand la copie est acceptee
337 objet.valeur = copy(self.valeur)
338 objet.val = copy(self.val)
340 for obj in self.mc_liste:
342 new_obj.reparent(objet)
343 objet.mc_liste.append(new_obj)
346 def get_sd_utilisees(self):
348 Retourne la liste des concepts qui sont utilisés à l'intérieur de self
349 ( comme valorisation d'un MCS)
352 for child in self.mc_liste:
353 l.extend(child.get_sd_utilisees())
356 def get_liste_mc_inconnus(self):
358 Retourne la liste des mots-clés inconnus dans self
361 if self.reste_val != {}:
362 for k,v in self.reste_val.items() :
363 l_mc.append([self,k,v])
364 for child in self.mc_liste :
365 if child.isvalid() : continue
366 l_child = child.get_liste_mc_inconnus()
373 def verif_condition_bloc(self):
375 Evalue les conditions de tous les blocs fils possibles
376 (en fonction du catalogue donc de la définition) de self
377 et retourne deux listes :
378 - la première contient les noms des blocs à rajouter
379 - la seconde contient les noms des blocs à supprimer
383 dict = self.cree_dict_valeurs(self.mc_liste)
384 for k,v in self.definition.entites.items():
386 globs= self.jdc and self.jdc.condition_context or {}
387 if v.verif_presence(dict,globs):
388 # le bloc doit être présent
389 if not self.get_child(k,restreint = 'oui'):
390 # le bloc n'est pas présent et il doit être créé
391 liste_ajouts.append(k)
393 # le bloc doit être absent
394 if self.get_child(k,restreint = 'oui'):
395 # le bloc est présent : il faut l'enlever
396 liste_retraits.append(k)
397 return liste_ajouts,liste_retraits
399 def reparent(self,parent):
401 Cette methode sert a reinitialiser la parente de l'objet
404 self.jdc=parent.get_jdc_root()
405 self.etape=parent.etape
406 for mocle in self.mc_liste:
409 def verif_existence_sd(self):
411 Vérifie que les structures de données utilisées dans self existent bien dans le contexte
412 avant étape, sinon enlève la référence à ces concepts
414 for motcle in self.mc_liste :
415 motcle.verif_existence_sd()