1 # -*- coding: utf-8 -*-
2 #@ MODIF N_ETAPE Noyau DATE 16/03/2004 AUTEUR GNICOLAS G.NICOLAS
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
6 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
7 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
8 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
9 # (AT YOUR OPTION) ANY LATER VERSION.
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
18 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
21 # ======================================================================
23 Ce module contient la classe ETAPE qui sert à vérifier et à exécuter
28 import types,sys,string,os
35 from N_Exception import AsException
37 from N_utils import AsType
39 class ETAPE(N_MCCOMPO.MCCOMPO):
41 Cette classe hérite de MCCOMPO car ETAPE est un OBJECT composite
46 # L'attribut de classe codex est utilisé pour rattacher le module de calcul éventuel (voir Build)
47 # On le met à None pour indiquer qu'il n'y a pas de module de calcul rattaché
50 def __init__(self,oper=None,reuse=None,args={}):
54 - definition : objet portant les attributs de définition d'une étape de type opérateur. Il
55 est initialisé par l'argument oper.
57 - reuse : indique le concept d'entrée réutilisé. Il se trouvera donc en sortie
58 si les conditions d'exécution de l'opérateur l'autorise
60 - valeur : arguments d'entrée de type mot-clé=valeur. Initialisé avec l'argument args.
67 self.parent=CONTEXT.get_current_step()
70 self.idracine=oper.label
71 self.appel=N_utils.callee_where()
77 def make_register(self):
79 Initialise les attributs jdc, id, niveau et réalise les
80 enregistrements nécessaires
83 self.jdc = self.parent.get_jdc_root()
84 self.id=self.parent.register(self)
87 self.jdc = self.parent =None
93 Cette methode a pour fonction de retirer tous les arguments egaux à None
94 de la liste des arguments. Ils sont supposés non présents et donc retirés.
96 for k in self.valeur.keys():
97 if self.valeur[k] == None:del self.valeur[k]
101 Demande la construction des sous-objets et les stocke dans l'attribut
104 self.mc_liste=self.build_mc()
106 def Build_sd(self,nom):
108 Construit le concept produit de l'opérateur. Deux cas
109 peuvent se présenter :
111 - le parent n'est pas défini. Dans ce cas, l'étape prend en charge la création
112 et le nommage du concept.
114 - le parent est défini. Dans ce cas, l'étape demande au parent la création et
115 le nommage du concept.
118 if not self.isactif():return
122 sd= self.parent.create_sdprod(self,nom)
123 if type(self.definition.op_init) == types.FunctionType:
124 apply(self.definition.op_init,(self,self.parent.g_context))
126 sd=self.get_sd_prod()
127 # On n'utilise pas self.definition.op_init car self.parent
129 if sd != None and self.reuse == None:
130 # On ne nomme le concept que dans le cas de non reutilisation
133 except AsException,e:
134 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
135 'fichier : ',self.appel[1],e)
139 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
140 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
141 'fichier : ',self.appel[1]+'\n',
149 Cette methode est un point d'entree prevu pour realiser une execution immediatement
150 apres avoir construit les mots cles et le concept produit.
151 Par defaut, elle ne fait rien. Elle doit etre surchargee dans une autre partie du programme.
155 def get_sd_prod(self):
157 Retourne le concept résultat de l'étape
159 cas 1 : sd_prod de oper n'est pas une fonction
160 il s'agit d'une sous classe de ASSD
161 on construit le sd à partir de cette classe
163 cas 2 : il s'agit d'une fonction
164 on l'évalue avec les mots-clés de l'étape (mc_liste)
165 on construit le sd à partir de la classe obtenue
168 if type(self.definition.sd_prod) == types.FunctionType:
169 d=self.cree_dict_valeurs(self.mc_liste)
171 sd_prod= apply(self.definition.sd_prod,(),d)
175 if CONTEXT.debug: traceback.print_exc()
176 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],
178 raise AsException("impossible d affecter un type au resultat",
180 # sys.exc_info()[0],sys.exc_info()[1],)
182 sd_prod=self.definition.sd_prod
183 # on teste maintenant si la SD est réutilisée ou s'il faut la créer
184 if self.definition.reentrant != 'n' and self.reuse:
185 # Le concept produit est specifie reutilise (reuse=xxx). C'est une erreur mais non fatale.
186 # Elle sera traitee ulterieurement.
189 self.sd= sd_prod(etape=self)
190 # Si l'operateur est obligatoirement reentrant et reuse n'a pas ete specifie, c'est une erreur.
191 # On ne fait rien ici. L'erreur sera traiter par la suite.
194 def get_type_produit(self):
196 Retourne le type du concept résultat de l'étape
198 cas 1 : sd_prod de oper n'est pas une fonction
199 il s'agit d'une sous classe de ASSD
200 on retourne le nom de la classe
201 cas 2 : il s'agit d'une fonction
202 on l'évalue avec les mots-clés de l'étape (mc_liste)
203 et on retourne son résultat
205 if type(self.definition.sd_prod) == types.FunctionType:
206 d=self.cree_dict_valeurs(self.mc_liste)
208 sd_prod= apply(self.definition.sd_prod,(),d)
210 #traceback.print_exc()
213 sd_prod=self.definition.sd_prod
218 Retourne l'étape à laquelle appartient self
219 Un objet de la catégorie etape doit retourner self pour indiquer que
220 l'étape a été trouvée
221 XXX fait double emploi avec self.etape ????
227 Méthode qui supprime toutes les références arrières afin que l'objet puisse
228 etre correctement détruit par le garbage collector
230 N_MCCOMPO.MCCOMPO.supprime(self)
233 if self.sd : self.sd.supprime()
237 Indique si l'étape est active (1) ou inactive (0)
241 def set_current_step(self):
243 Methode utilisee pour que l etape self se declare etape
244 courante. Utilise par les macros
246 #print "set_current_step ",self.nom
247 #traceback.print_stack(limit=3,file=sys.stdout)
248 cs= CONTEXT.get_current_step()
249 if self.parent != cs :
250 raise "L'étape courante %s devrait etre le parent de self : %s" % (cs,self)
252 CONTEXT.unset_current_step()
253 CONTEXT.set_current_step(self)
255 def reset_current_step(self):
257 Methode utilisee par l'etape self qui remet son etape parent comme
260 #print "reset_current_step ",self.nom
261 #traceback.print_stack(limit=3,file=sys.stdout)
262 cs= CONTEXT.get_current_step()
264 raise "L'étape courante %s devrait etre self : %s" % (cs,self)
266 CONTEXT.unset_current_step()
267 CONTEXT.set_current_step(self.parent)
269 def issubstep(self,etape):
271 Cette methode retourne un entier indiquant si etape est une
272 sous etape de self ou non
275 Une étape simple n'a pas de sous etape
279 def get_file(self,unite=None,fic_origine=''):
281 Retourne le nom du fichier associe a l unite logique unite (entier)
282 ainsi que le source contenu dans le fichier
284 if self.jdc : return self.jdc.get_file(unite=unite,fic_origine=fic_origine)
288 if os.path.exists("fort."+str(unite)):
289 file= "fort."+str(unite)
291 raise AsException("Impossible de trouver le fichier correspondant a l unite %s" % unite)
292 if not os.path.exists(file):
293 raise AsException("%s n'est pas un fichier existant" % unite)
295 text=string.replace(fproc.read(),'\r\n','\n')
297 linecache.cache[file]=0,0,string.split(text,'\n'),file
300 def accept(self,visitor):
302 Cette methode permet de parcourir l'arborescence des objets
303 en utilisant le pattern VISITEUR
305 visitor.visitETAPE(self)
307 def update_context(self,d):
309 Cette methode doit updater le contexte fournit par
310 l'appelant en argument (d) en fonction de sa definition
312 if type(self.definition.op_init) == types.FunctionType:
313 apply(self.definition.op_init,(self,d))
315 d[self.sd.nom]=self.sd
318 """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
323 etape.state = 'modified'
328 for objet in self.mc_liste:
329 new_obj = objet.copy()
330 new_obj.reparent(etape)
331 etape.mc_liste.append(new_obj)
334 def copy_reuse(self,old_etape):
335 """ Méthode qui copie le reuse d'une autre étape.
337 if hasattr(old_etape,"reuse") :
338 self.reuse = old_etape.reuse
340 def copy_sdnom(self,old_etape):
341 """ Méthode qui copie le sdnom d'une autre étape.
343 if hasattr(old_etape,"sdnom") :
344 self.sdnom = old_etape.sdnom
346 def get_sd_utilisees(self):
348 Retourne la liste des concepts qui sont utilisés à l'intérieur d'une commande
349 ( comme valorisation d'un MCS)
352 for child in self.mc_liste:
353 l.extend(child.get_sd_utilisees())
356 def get_sd_mcs_utilisees(self):
358 Retourne la ou les SD utilisée par self sous forme d'un dictionnaire :
359 . Si aucune sd n'est utilisée, le dictionnaire est vide.
360 . Sinon, les clés du dictionnaire sont les mots-clés derrière lesquels on
361 trouve des sd ; la valeur est la liste des sd attenante.
362 Exemple : { 'VALE_F': [ <Cata.cata.para_sensi instance at 0x9419854>,
363 <Cata.cata.para_sensi instance at 0x941a204> ],
364 'MODELE': [<Cata.cata.modele instance at 0x941550c>] }
367 for child in self.mc_liste:
368 daux = child.get_sd_mcs_utilisees()
369 for cle in daux.keys():
370 dico[cle] = daux[cle]
373 def reparent(self,parent):
375 Cette methode sert a reinitialiser la parente de l'objet
378 self.jdc=parent.get_jdc_root()
380 for mocle in self.mc_liste:
383 def get_cmd(self,nomcmd):
385 Méthode pour recuperer la definition d'une commande
386 donnee par son nom dans les catalogues declares
388 Appele par un ops d'une macro en Python
390 return self.jdc.get_cmd(nomcmd)
392 def copy_intern(self,etape):
394 Méthode permettant lors du processus de recopie de copier
395 les elements internes d'une etape dans une autre
399 def full_copy(self,parent=None):
401 Méthode permettant d'effectuer une copie complète
402 d'une étape (y compris concept produit, éléments internes)
403 Si l'argument parent est fourni, la nouvelle étape
404 aura cet objet comme parent.
406 new_etape = self.copy()
407 new_etape.copy_reuse(self)
408 new_etape.copy_sdnom(self)
409 if parent: new_etape.reparent(parent)
411 new_sd = self.sd.__class__(etape=new_etape)
412 new_etape.sd = new_sd
413 if self.reuse == None :
414 new_etape.parent.NommerSdprod(new_sd,self.sd.nom)
416 new_sd.nom = self.sd.nom
417 new_etape.copy_intern(self)