1 #@ MODIF N_ETAPE Noyau DATE 10/05/2006 AUTEUR MCOURTOI M.COURTOIS
2 # -*- coding: iso-8859-1 -*-
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 # ======================================================================
25 Ce module contient la classe ETAPE qui sert à vérifier et à exécuter
30 import types,sys,string,os
37 from N_Exception import AsException
39 from N_utils import AsType
41 class ETAPE(N_MCCOMPO.MCCOMPO):
43 Cette classe hérite de MCCOMPO car ETAPE est un OBJECT composite
48 # L'attribut de classe codex est utilisé pour rattacher le module de calcul éventuel (voir Build)
49 # On le met à None pour indiquer qu'il n'y a pas de module de calcul rattaché
52 def __init__(self,oper=None,reuse=None,args={}):
56 - definition : objet portant les attributs de définition d'une étape de type opérateur. Il
57 est initialisé par l'argument oper.
59 - reuse : indique le concept d'entrée réutilisé. Il se trouvera donc en sortie
60 si les conditions d'exécution de l'opérateur l'autorise
62 - valeur : arguments d'entrée de type mot-clé=valeur. Initialisé avec l'argument args.
69 self.parent=CONTEXT.get_current_step()
72 self.idracine=oper.label
73 self.appel=N_utils.callee_where()
79 def make_register(self):
81 Initialise les attributs jdc, id, niveau et réalise les
82 enregistrements nécessaires
85 self.jdc = self.parent.get_jdc_root()
86 self.id=self.parent.register(self)
89 self.jdc = self.parent =None
95 Cette methode a pour fonction de retirer tous les arguments egaux à None
96 de la liste des arguments. Ils sont supposés non présents et donc retirés.
98 for k in self.valeur.keys():
99 if self.valeur[k] == None:del self.valeur[k]
103 Demande la construction des sous-objets et les stocke dans l'attribut
106 self.mc_liste=self.build_mc()
108 def Build_sd(self,nom):
110 Construit le concept produit de l'opérateur. Deux cas
111 peuvent se présenter :
113 - le parent n'est pas défini. Dans ce cas, l'étape prend en charge la création
114 et le nommage du concept.
116 - le parent est défini. Dans ce cas, l'étape demande au parent la création et
117 le nommage du concept.
123 sd= self.parent.create_sdprod(self,nom)
124 if type(self.definition.op_init) == types.FunctionType:
125 apply(self.definition.op_init,(self,self.parent.g_context))
127 sd=self.get_sd_prod()
128 # On n'utilise pas self.definition.op_init car self.parent
130 if sd != None and self.reuse == None:
131 # On ne nomme le concept que dans le cas de non reutilisation
134 except AsException,e:
135 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
136 'fichier : ',self.appel[1],e)
140 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
141 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
142 'fichier : ',self.appel[1]+'\n',
150 Cette methode est un point d'entree prevu pour realiser une execution immediatement
151 apres avoir construit les mots cles et le concept produit.
152 Par defaut, elle ne fait rien. Elle doit etre surchargee dans une autre partie du programme.
156 def get_sd_prod(self):
158 Retourne le concept résultat de l'étape
160 cas 1 : sd_prod de oper n'est pas une fonction
161 il s'agit d'une sous classe de ASSD
162 on construit le sd à partir de cette classe
164 cas 2 : il s'agit d'une fonction
165 on l'évalue avec les mots-clés de l'étape (mc_liste)
166 on construit le sd à partir de la classe obtenue
169 if type(self.definition.sd_prod) == types.FunctionType:
170 d=self.cree_dict_valeurs(self.mc_liste)
172 sd_prod= apply(self.definition.sd_prod,(),d)
176 if CONTEXT.debug: traceback.print_exc()
177 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],
179 raise AsException("impossible d affecter un type au resultat",
181 # sys.exc_info()[0],sys.exc_info()[1],)
183 sd_prod=self.definition.sd_prod
184 # on teste maintenant si la SD est réutilisée ou s'il faut la créer
185 if self.definition.reentrant != 'n' and self.reuse:
186 # Le concept produit est specifie reutilise (reuse=xxx). C'est une erreur mais non fatale.
187 # Elle sera traitee ulterieurement.
190 self.sd= sd_prod(etape=self)
191 # Si l'operateur est obligatoirement reentrant et reuse n'a pas ete specifie, c'est une erreur.
192 # On ne fait rien ici. L'erreur sera traiter par la suite.
195 def get_type_produit(self):
197 return self.get_type_produit_brut()
201 def get_type_produit_brut(self):
203 Retourne le type du concept résultat de l'étape
205 cas 1 : sd_prod de oper n'est pas une fonction
206 il s'agit d'une sous classe de ASSD
207 on retourne le nom de la classe
208 cas 2 : il s'agit d'une fonction
209 on l'évalue avec les mots-clés de l'étape (mc_liste)
210 et on retourne son résultat
212 if type(self.definition.sd_prod) == types.FunctionType:
213 d=self.cree_dict_valeurs(self.mc_liste)
214 sd_prod= apply(self.definition.sd_prod,(),d)
216 sd_prod=self.definition.sd_prod
221 Retourne l'étape à laquelle appartient self
222 Un objet de la catégorie etape doit retourner self pour indiquer que
223 l'étape a été trouvée
224 XXX fait double emploi avec self.etape ????
230 Méthode qui supprime toutes les références arrières afin que l'objet puisse
231 etre correctement détruit par le garbage collector
233 N_MCCOMPO.MCCOMPO.supprime(self)
236 if self.sd : self.sd.supprime()
240 Indique si l'étape est active (1) ou inactive (0)
244 def set_current_step(self):
246 Methode utilisee pour que l etape self se declare etape
247 courante. Utilise par les macros
249 #print "set_current_step ",self.nom
250 #traceback.print_stack(limit=3,file=sys.stdout)
251 cs= CONTEXT.get_current_step()
252 if self.parent != cs :
253 raise "L'étape courante %s devrait etre le parent de self : %s" % (cs,self)
255 CONTEXT.unset_current_step()
256 CONTEXT.set_current_step(self)
258 def reset_current_step(self):
260 Methode utilisee par l'etape self qui remet son etape parent comme
263 #print "reset_current_step ",self.nom
264 #traceback.print_stack(limit=3,file=sys.stdout)
265 cs= CONTEXT.get_current_step()
267 raise "L'étape courante %s devrait etre self : %s" % (cs,self)
269 CONTEXT.unset_current_step()
270 CONTEXT.set_current_step(self.parent)
272 def issubstep(self,etape):
274 Cette methode retourne un entier indiquant si etape est une
275 sous etape de self ou non
278 Une étape simple n'a pas de sous etape
282 def get_file(self,unite=None,fic_origine=''):
284 Retourne le nom du fichier associe a l unite logique unite (entier)
285 ainsi que le source contenu dans le fichier
287 if self.jdc : return self.jdc.get_file(unite=unite,fic_origine=fic_origine)
291 if os.path.exists("fort."+str(unite)):
292 file= "fort."+str(unite)
294 raise AsException("Impossible de trouver le fichier correspondant a l unite %s" % unite)
295 if not os.path.exists(file):
296 raise AsException("%s n'est pas un fichier existant" % unite)
298 text=string.replace(fproc.read(),'\r\n','\n')
300 linecache.cache[file]=0,0,string.split(text,'\n'),file
303 def accept(self,visitor):
305 Cette methode permet de parcourir l'arborescence des objets
306 en utilisant le pattern VISITEUR
308 visitor.visitETAPE(self)
310 def update_context(self,d):
312 Cette methode doit updater le contexte fournit par
313 l'appelant en argument (d) en fonction de sa definition
315 if type(self.definition.op_init) == types.FunctionType:
316 apply(self.definition.op_init,(self,d))
318 d[self.sd.nom]=self.sd
321 """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
326 etape.state = 'modified'
331 for objet in self.mc_liste:
332 new_obj = objet.copy()
333 new_obj.reparent(etape)
334 etape.mc_liste.append(new_obj)
337 def copy_reuse(self,old_etape):
338 """ Méthode qui copie le reuse d'une autre étape.
340 if hasattr(old_etape,"reuse") :
341 self.reuse = old_etape.reuse
343 def copy_sdnom(self,old_etape):
344 """ Méthode qui copie le sdnom d'une autre étape.
346 if hasattr(old_etape,"sdnom") :
347 self.sdnom = old_etape.sdnom
349 def reparent(self,parent):
351 Cette methode sert a reinitialiser la parente de l'objet
354 self.jdc=parent.get_jdc_root()
356 for mocle in self.mc_liste:
358 if self.sd and self.reuse == None :
361 def get_cmd(self,nomcmd):
363 Méthode pour recuperer la definition d'une commande
364 donnee par son nom dans les catalogues declares
366 Appele par un ops d'une macro en Python
368 return self.jdc.get_cmd(nomcmd)
370 def copy_intern(self,etape):
372 Méthode permettant lors du processus de recopie de copier
373 les elements internes d'une etape dans une autre
377 def full_copy(self,parent=None):
379 Méthode permettant d'effectuer une copie complète
380 d'une étape (y compris concept produit, éléments internes)
381 Si l'argument parent est fourni, la nouvelle étape
382 aura cet objet comme parent.
384 new_etape = self.copy()
385 new_etape.copy_reuse(self)
386 new_etape.copy_sdnom(self)
387 if parent: new_etape.reparent(parent)
389 new_sd = self.sd.__class__(etape=new_etape)
390 new_etape.sd = new_sd
391 if self.reuse == None :
392 new_etape.parent.NommerSdprod(new_sd,self.sd.nom)
394 new_sd.nom = self.sd.nom
395 new_etape.copy_intern(self)
398 def reset_jdc(self,new_jdc):
400 Reinitialise le nommage du concept de l'etape lors d'un changement de jdc
402 if self.sd and self.reuse == None :
403 self.parent.NommerSdprod(self.sd,self.sd.nom)