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)
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 replace_concept(self,old_sd,sd):
315 - old_sd=concept remplace
316 - sd = nouveau concept
318 Mettre a jour les fils de l objet suite au remplacement du
321 for child in self.mc_liste :
322 child.replace_concept(old_sd,sd)
324 def delete_mc_global(self,mc):
326 Supprime le mot-clé mc de la liste des mots-clés globaux de l'étape
328 etape = self.get_etape()
331 del etape.mc_globaux[nom]
333 def delete_mc_global_jdc(self,mc):
335 Supprime le mot-clé mc de la liste des mots-clés globaux du jdc
338 del self.jdc.mc_globaux[nom]
340 def get_liste_mc_inconnus(self):
342 Retourne la liste des mots-clés inconnus dans self
345 if self.reste_val != {}:
346 for k,v in self.reste_val.items() :
347 l_mc.append([self,k,v])
348 for child in self.mc_liste :
349 if child.isvalid() : continue
350 l_child = child.get_liste_mc_inconnus()
357 def verif_condition_bloc(self):
359 Evalue les conditions de tous les blocs fils possibles
360 (en fonction du catalogue donc de la définition) de self
361 et retourne deux listes :
362 - la première contient les noms des blocs à rajouter
363 - la seconde contient les noms des blocs à supprimer
367 dict = self.cree_dict_condition(self.mc_liste)
368 for k,v in self.definition.entites.items():
370 globs= self.jdc and self.jdc.condition_context or {}
371 if v.verif_presence(dict,globs):
372 # le bloc doit être présent
373 if not self.get_child(k,restreint = 'oui'):
374 # le bloc n'est pas présent et il doit être créé
375 liste_ajouts.append(k)
377 # le bloc doit être absent
378 if self.get_child(k,restreint = 'oui'):
379 # le bloc est présent : il faut l'enlever
380 liste_retraits.append(k)
381 return liste_ajouts,liste_retraits
383 def verif_existence_sd(self):
385 Vérifie que les structures de données utilisées dans self existent bien dans le contexte
386 avant étape, sinon enlève la référence à ces concepts
388 for motcle in self.mc_liste :
389 motcle.verif_existence_sd()