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 # ======================================================================
23 import types,traceback
24 import string,linecache
28 from Noyau.N_ASSD import ASSD
29 from Noyau.N_ETAPE import ETAPE
30 from Noyau.N_Exception import AsException
31 from Extensions import commentaire,parametre,parametre_eval
33 class JDC(I_OBJECT.OBJECT):
38 self.etapes_niveaux=[]
42 self._etape_context=None
44 def get_cmd(self,nomcmd):
46 Retourne l'objet de type COMMANDE de nom nomcmd
48 for cata in self.cata:
49 if hasattr(cata,nomcmd):
50 return getattr(cata,nomcmd)
52 def get_sd_avant_du_bon_type(self,etape,types_permis):
54 Retourne la liste des concepts avant etape d'un type acceptable
56 d=self.get_contexte_avant(etape)
59 if type(v) != types.InstanceType : continue
60 # On considère que seul assd indique un type quelconque pas CO
61 elif self.assd in types_permis :
63 elif self.est_permis(v,types_permis):
68 def est_permis(self,v,types_permis):
69 for type_ok in types_permis:
70 if type_ok in ('R','I','C','TXM') and v in self.params :
72 elif type_ok == 'R' and v.__class__.__name__ == 'reel' :
74 elif type_ok == 'I' and v.__class__.__name__ == 'entier' :
76 elif type_ok == 'C' and v.__class__.__name__ == 'complexe' :
78 elif type_ok == 'TXM' and v.__class__.__name__ == 'chaine' :
80 elif type(type_ok) != types.ClassType :
82 elif v.__class__ == type_ok or issubclass(v.__class__,type_ok):
86 def addentite(self,name,pos):
89 Si name est le nom d une commande ou un commentaire ajoute
91 Sinon remonte une erreur
95 if name == "COMMENTAIRE" :
96 # ajout d'un commentaire
97 self.set_current_step()
99 for child in self.etapes :
100 if isinstance(child,commentaire.COMMENTAIRE):
102 objet = commentaire.COMMENTAIRE('',parent=self)
103 objet.nom = "_comm_"+`ind`
104 if pos == None : pos = 0
105 self.etapes.insert(pos,objet)
109 elif name == "PARAMETRE":
110 # ajout d'un parametre
111 self.set_current_step()
112 nom_param = '_param_'+str(len(self.params)+1)
113 objet = parametre.PARAMETRE(nom=nom_param)
114 if pos == None : pos = 0
115 self.etapes.insert(pos,objet)
120 elif name == "PARAMETRE_EVAL":
121 # ajout d'un parametre EVAL
122 self.set_current_step()
123 nom_param = '_param_'+str(len(self.params)+1)
124 objet = parametre_eval.PARAMETRE_EVAL(nom=nom_param)
125 if pos == None : pos = 0
126 self.etapes.insert(pos,objet)
131 elif type(name)==types.InstanceType:
132 # on est dans le cas où on veut ajouter une commande déjà
133 # existante (par copie donc)
134 # on est donc nécessairement en mode editeur ...
136 # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
138 self.set_current_step()
139 if isinstance(objet,ETAPE):
140 if objet.nom_niveau_definition == 'JDC':
141 # l'objet dépend directement du JDC
144 # l'étape dépend d'un niveau et non directement du JDC :
145 # il faut l'enregistrer dans le niveau de parent
146 objet.parent.dict_niveaux[objet.nom_niveau_definition].register(objet)
147 objet.niveau = objet.parent.dict_niveaux[objet.nom_niveau_definition]
148 self.etapes.insert(pos,objet)
149 # il faut vérifier que les concepts utilisés par objet existent bien
150 # à ce niveau d'arborescence
151 objet.verif_existence_sd()
157 # On veut ajouter une nouvelle commande
159 self.set_current_step()
160 cmd=self.get_cmd(name)
161 # L'appel a make_objet n'a pas pour effet d'enregistrer l'étape
162 # auprès du step courant car editmode vaut 1
163 # Par contre elle a le bon parent grace a set_current_step
165 if pos == None : pos = 0
166 self.etapes.insert(pos,e)
167 self.reset_current_step()
173 traceback.print_exc()
174 self.reset_current_step()
176 raise AsException("Impossible d ajouter la commande "+name)
178 def set_current_step(self):
179 CONTEXT.unset_current_step()
180 CONTEXT.set_current_step(self)
182 def reset_current_step(self):
183 CONTEXT.unset_current_step()
185 def liste_mc_presents(self):
188 def get_sd_avant_etape(self,nom_sd,etape):
189 return self.get_contexte_avant(etape).get(nom_sd,None)
191 def get_sd_apres_etape(self,nom_sd,etape,avec='non'):
193 Cette méthode retourne la SD de nom nom_sd qui est éventuellement
195 Si avec vaut 'non' exclut etape de la recherche
197 ietap=self.etapes.index(etape)
198 if avec == 'non':ietap=ietap+1
199 for e in self.etapes[ietap:]:
200 sd=e.get_sdprods(nom_sd)
202 if hasattr(e,'reuse'):
207 def get_sd_autour_etape(self,nom_sd,etape,avec='non'):
209 Fonction: retourne la SD de nom nom_sd qui est éventuellement
210 définie avant ou apres etape
211 Permet de vérifier si un concept de meme nom existe dans le périmètre
213 Si avec vaut 'non' exclut etape de la recherche
215 sd=self.get_sd_avant_etape(nom_sd,etape)
217 return self.get_sd_apres_etape(nom_sd,etape,avec)
219 def active_etapes(self):
221 Cette méthode a pour fonction de désactiver les étapes qui doivent
222 l'être cad, dans le cas d'ASTER, les étapes qui ne sont pas
223 comprises entre le premier DEBUT/POURSUITE et le premier FIN
224 et rendre actives les autres
226 if self.definition.code == 'ASTER' :
227 # Seulement pour ASTER :
228 # Avant DEBUT actif vaut 0
229 # Apres DEBUT et avant le 1er FIN actif vaut 1
230 # Apres le 1er FIN actif vaut -1
234 for etape in self.etapes:
235 if actif == 0 and etape.nom in ['DEBUT','POURSUITE']:actif=1
240 if etape.nom == 'FIN':actif=-1
242 def suppentite(self,etape) :
244 Cette methode a pour fonction de supprimer une étape dans
248 self.etapes.remove(etape)
249 if etape.niveau is not self:
250 # Dans ce cas l'étape est enregistrée dans un niveau
251 # Il faut la désenregistrer
252 etape.niveau.unregister(etape)
253 etape.supprime_sdprods()
256 def del_sdprod(self,sd):
258 Supprime la SD sd de la liste des sd et des dictionnaires de contexte
260 if sd in self.sds : self.sds.remove(sd)
261 if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
263 def delete_concept(self,sd):
268 Mettre a jour les etapes du JDC suite à la disparition du
270 Seuls les mots cles simples MCSIMP font un traitement autre
271 que de transmettre aux fils
273 for etape in self.etapes :
274 etape.delete_concept(sd)
278 if not self.cr.estvide():return
282 def register(self,etape):
284 Cette méthode ajoute etape dans la liste
285 des etapes self.etapes et retourne l identificateur d'étape
286 fourni par l appel a g_register
287 A quoi sert editmode ?
288 - Si editmode vaut 1, on est en mode edition de JDC. On cherche
289 à enregistrer une étape que l'on a créée avec eficas (en passant
290 par addentite) auquel cas on ne veut récupérer que son numéro
291 d'enregistrement et c'est addentité qui l'enregistre dans
292 self.etapes à la bonne place...
293 - Si editmode vaut 0, on est en mode relecture d'un fichier de
294 commandes et on doit enregistrer l'étape à la fin de self.etapes
295 (dans ce cas l'ordre des étapes est bien l'ordre chronologique
298 if not self.editmode:
299 self.etapes.append(etape)
302 return self.g_register(etape)
304 def register_parametre(self,param):
306 Cette méthode sert à ajouter un paramètre dans la liste des paramètres
308 self.params.append(param)
310 def register_fonction(self,fonction):
312 Cette méthode sert à ajouter une fonction dans la liste des fonctions
314 self.fonctions.append(fonction)
316 def delete_param(self,param):
318 Supprime le paramètre param de la liste des paramètres
321 if param in self.params : self.params.remove(param)
322 if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
324 def get_parametres_fonctions_avant_etape(self,etape):
326 Retourne deux éléments :
327 - une liste contenant les noms des paramètres (constantes ou EVAL)
329 - une liste contenant les formules définies avant etape
333 # on récupère le contexte avant etape
334 # on ne peut mettre dans les deux listes que des éléments de ce contexte
335 d=self.get_contexte_avant(etape)
336 # construction de l_constantes
337 for param in self.params:
339 if not nom : continue
340 if d.has_key(nom): l_constantes.append(nom)
341 # construction de l_fonctions
342 for form in self.fonctions:
344 if not nom : continue
345 if d.has_key(nom): l_fonctions.append(form.get_formule())
347 # on ajoute les concepts produits par DEFI_VALEUR
348 # XXX On pourrait peut etre faire plutot le test sur le type
349 # de concept : entier, reel, complexe, etc.
350 for k,v in d.items():
351 if hasattr(v,'etape') and v.etape.nom in ('DEFI_VALEUR',):
352 l_constantes.append(k)
354 # on retourne les deux listes
355 return l_constantes,l_fonctions
357 def get_nb_etapes_avant(self,niveau):
359 Retourne le nombre d etapes avant le debut de niveau
362 for niv in self.etapes_niveaux:
363 if niv == niveau:break
364 nb=nb+len(niv.etapes)
367 def send_message(self,message):
369 self.appli.send_message(message)
371 #XXX ne semble pas servir pour JDC
372 # def reevalue_sd_jdc(self):
374 #Avec la liste des SD qui ont été supprimées, propage la disparition de ces
375 #SD dans toutes les étapes et descendants
377 #l_sd = self.diff_contextes()
378 #if len(l_sd) == 0 : return
380 #self.jdc.delete_concept(sd)
382 def init_modif(self):
384 Méthode appelée au moment où une modification va être faite afin de
385 déclencher d'éventuels traitements pré-modification
387 self.state = 'modified'
392 def get_liste_mc_inconnus(self):
394 Retourne une liste contenant les mots-clés inconnus à la relecture du JDC
396 # cette liste a le format suivant : [etape,(bloc,mcfact,...),nom_mc,valeur_mc]
398 for etape in self.etapes :
400 if not etape.isvalid() :
401 l = etape.get_liste_mc_inconnus()
402 if l : l_mc.extend(l)
405 def get_file(self,unite=None,fic_origine=''):
407 Retourne le nom du fichier correspondant à un numero d'unité
408 logique (entier) ainsi que le source contenu dans le fichier
411 # Si le JDC est relié à une application maitre, on délègue la recherche
412 file,text = self.appli.get_file(unite,fic_origine)
416 if os.path.exists("fort."+str(unite)):
417 file= "fort."+str(unite)
419 raise AsException("Impossible de trouver le fichier correspondant \
420 a l unite %s" % unite)
421 if not os.path.exists(file):
422 raise AsException("%s n'est pas un fichier existant" % unite)
426 text=string.replace(text,'\r\n','\n')
427 linecache.cache[file]=0,0,string.split(text,'\n'),file
431 def get_genealogie(self):
433 Retourne la liste des noms des ascendants de l'objet self
434 jusqu'à la première ETAPE parent.
438 def NommerSdprod(self,sd,sdnom):
440 Nomme la SD apres avoir verifie que le nommage est possible : nom
442 Si le nom est deja utilise, leve une exception
443 Met le concept créé dans le concept global g_context
445 # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
446 # Le dictionnaire g_context ne représente pas le contexte
447 # effectif avant une étape.
448 # Il faut utiliser get_contexte_avant avec une indication de l'étape
449 # traitée. Pour le moment, il n'y a pas de moyen de le faire : ajouter
450 # un attribut dans le JDC ???
451 if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
452 if self._etape_context:
453 o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
455 o=self.g_context.get(sdnom,None)
456 if isinstance(o,ASSD):
457 raise AsException("Nom de concept deja defini : %s" % sdnom)
459 # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
460 # Ajoute a la creation (appel de reg_sd).
461 self.g_context[sdnom]=sd
464 def set_etape_context(self,etape):
466 Positionne l'etape qui sera utilisee dans NommerSdProd pour
467 decider si le concept passé pourra etre nommé
469 self._etape_context=etape
471 def reset_context(self):
473 Cette methode reinitialise le contexte glissant pour pouvoir
474 tenir compte des modifications de l'utilisateur : création
475 de commandes, nommage de concepts, etc.
477 self.current_context={}
478 self.index_etape_courante=0
480 def del_param(self,param):
482 Supprime le paramètre param de la liste des paramètres
485 if param in self.params : self.params.remove(param)
486 if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
488 def del_fonction(self,fonction):
490 Supprime la fonction fonction de la liste des fonctions
493 if fonction in self.fonctions : self.fonctions.remove(fonction)
494 if self.g_context.has_key(fonction.nom) : del self.g_context[fonction.nom]