1 #@ MODIF N_ETAPE Noyau DATE 26/09/2003 AUTEUR DURAND C.DURAND
2 # CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
20 # ======================================================================
22 Ce module contient la classe ETAPE qui sert à vérifier et à exécuter
27 import types,sys,string,os
34 from N_Exception import AsException
36 from N_utils import AsType
38 class ETAPE(N_MCCOMPO.MCCOMPO):
40 Cette classe hérite de MCCOMPO car ETAPE est un OBJECT composite
45 # L'attribut de classe codex est utilisé pour rattacher le module de calcul éventuel (voir Build)
46 # On le met à None pour indiquer qu'il n'y a pas de module de calcul rattaché
49 def __init__(self,oper=None,reuse=None,args={}):
53 - definition : objet portant les attributs de définition d'une étape de type opérateur. Il
54 est initialisé par l'argument oper.
56 - reuse : indique le concept d'entrée réutilisé. Il se trouvera donc en sortie
57 si les conditions d'exécution de l'opérateur l'autorise
59 - valeur : arguments d'entrée de type mot-clé=valeur. Initialisé avec l'argument args.
66 self.parent=CONTEXT.get_current_step()
69 self.idracine=oper.label
70 self.appel=N_utils.callee_where()
76 def make_register(self):
78 Initialise les attributs jdc, id, niveau et réalise les
79 enregistrements nécessaires
82 self.jdc = self.parent.get_jdc_root()
83 self.id=self.parent.register(self)
86 self.jdc = self.parent =None
92 Cette methode a pour fonction de retirer tous les arguments egaux à None
93 de la liste des arguments. Ils sont supposés non présents et donc retirés.
95 for k in self.valeur.keys():
96 if self.valeur[k] == None:del self.valeur[k]
100 Demande la construction des sous-objets et les stocke dans l'attribut
103 self.mc_liste=self.build_mc()
105 def Build_sd(self,nom):
107 Construit le concept produit de l'opérateur. Deux cas
108 peuvent se présenter :
110 - le parent n'est pas défini. Dans ce cas, l'étape prend en charge la création
111 et le nommage du concept.
113 - le parent est défini. Dans ce cas, l'étape demande au parent la création et
114 le nommage du concept.
117 if not self.isactif():return
121 sd= self.parent.create_sdprod(self,nom)
122 if type(self.definition.op_init) == types.FunctionType:
123 apply(self.definition.op_init,(self,self.parent.g_context))
125 sd=self.get_sd_prod()
126 # On n'utilise pas self.definition.op_init car self.parent
128 if sd != None and self.reuse == None:
129 # On ne nomme le concept que dans le cas de non reutilisation
132 except AsException,e:
133 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
134 'fichier : ',self.appel[1],e)
138 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
139 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
140 'fichier : ',self.appel[1]+'\n',
148 Cette methode est un point d'entree prevu pour realiser une execution immediatement
149 apres avoir construit les mots cles et le concept produit.
150 Par defaut, elle ne fait rien. Elle doit etre surchargee dans une autre partie du programme.
154 def get_sd_prod(self):
156 Retourne le concept résultat de l'étape
158 cas 1 : sd_prod de oper n'est pas une fonction
159 il s'agit d'une sous classe de ASSD
160 on construit le sd à partir de cette classe
162 cas 2 : il s'agit d'une fonction
163 on l'évalue avec les mots-clés de l'étape (mc_liste)
164 on construit le sd à partir de la classe obtenue
167 if type(self.definition.sd_prod) == types.FunctionType:
168 d=self.cree_dict_valeurs(self.mc_liste)
170 sd_prod= apply(self.definition.sd_prod,(),d)
174 if CONTEXT.debug: traceback.print_exc()
175 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],
177 raise AsException("impossible d affecter un type au resultat",
179 # sys.exc_info()[0],sys.exc_info()[1],)
181 sd_prod=self.definition.sd_prod
182 # on teste maintenant si la SD est réutilisée ou s'il faut la créer
183 if self.definition.reentrant != 'n' and self.reuse:
184 # Le concept produit est specifie reutilise (reuse=xxx). C'est une erreur mais non fatale.
185 # Elle sera traitee ulterieurement.
188 self.sd= sd_prod(etape=self)
189 # Si l'operateur est obligatoirement reentrant et reuse n'a pas ete specifie, c'est une erreur.
190 # On ne fait rien ici. L'erreur sera traiter par la suite.
193 def get_type_produit(self):
195 Retourne le type du concept résultat de l'étape
197 cas 1 : sd_prod de oper n'est pas une fonction
198 il s'agit d'une sous classe de ASSD
199 on retourne le nom de la classe
200 cas 2 : il s'agit d'une fonction
201 on l'évalue avec les mots-clés de l'étape (mc_liste)
202 et on retourne son résultat
204 if type(self.definition.sd_prod) == types.FunctionType:
205 d=self.cree_dict_valeurs(self.mc_liste)
207 sd_prod= apply(self.definition.sd_prod,(),d)
209 #traceback.print_exc()
212 sd_prod=self.definition.sd_prod
217 Retourne l'étape à laquelle appartient self
218 Un objet de la catégorie etape doit retourner self pour indiquer que
219 l'étape a été trouvée
220 XXX fait double emploi avec self.etape ????
226 Méthode qui supprime toutes les références arrières afin que l'objet puisse
227 etre correctement détruit par le garbage collector
229 N_MCCOMPO.MCCOMPO.supprime(self)
232 if self.sd : self.sd.supprime()
236 Indique si l'étape est active (1) ou inactive (0)
240 def set_current_step(self):
242 Methode utilisee pour que l etape self se declare etape
243 courante. Utilise par les macros
245 #print "set_current_step ",self.nom
246 #traceback.print_stack(limit=3,file=sys.stdout)
247 cs= CONTEXT.get_current_step()
248 if self.parent != cs :
249 raise "L'étape courante %s devrait etre le parent de self : %s" % (cs,self)
251 CONTEXT.unset_current_step()
252 CONTEXT.set_current_step(self)
254 def reset_current_step(self):
256 Methode utilisee par l'etape self qui remet son etape parent comme
259 #print "reset_current_step ",self.nom
260 #traceback.print_stack(limit=3,file=sys.stdout)
261 cs= CONTEXT.get_current_step()
263 raise "L'étape courante %s devrait etre self : %s" % (cs,self)
265 CONTEXT.unset_current_step()
266 CONTEXT.set_current_step(self.parent)
268 def issubstep(self,etape):
270 Cette methode retourne un entier indiquant si etape est une
271 sous etape de self ou non
274 Une étape simple n'a pas de sous etape
278 def get_file(self,unite=None,fic_origine=''):
280 Retourne le nom du fichier associe a l unite logique unite (entier)
281 ainsi que le source contenu dans le fichier
283 if self.jdc : return self.jdc.get_file(unite=unite,fic_origine=fic_origine)
287 if os.path.exists("fort."+str(unite)):
288 file= "fort."+str(unite)
290 raise AsException("Impossible de trouver le fichier correspondant a l unite %s" % unite)
291 if not os.path.exists(file):
292 raise AsException("%s n'est pas un fichier existant" % unite)
294 text=string.replace(fproc.read(),'\r\n','\n')
296 linecache.cache[file]=0,0,string.split(text,'\n'),file
299 def accept(self,visitor):
301 Cette methode permet de parcourir l'arborescence des objets
302 en utilisant le pattern VISITEUR
304 visitor.visitETAPE(self)
306 def update_context(self,d):
308 Cette methode doit updater le contexte fournit par
309 l'appelant en argument (d) en fonction de sa definition
311 if type(self.definition.op_init) == types.FunctionType:
312 apply(self.definition.op_init,(self,d))
314 d[self.sd.nom]=self.sd
317 """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
322 etape.state = 'modified'
327 for objet in self.mc_liste:
328 new_obj = objet.copy()
329 new_obj.reparent(etape)
330 etape.mc_liste.append(new_obj)
333 def copy_reuse(self,old_etape):
334 """ Méthode qui copie le reuse d'une autre étape.
336 if hasattr(old_etape,"reuse") :
337 self.reuse = old_etape.reuse
339 def copy_sdnom(self,old_etape):
340 """ Méthode qui copie le sdnom d'une autre étape.
342 if hasattr(old_etape,"sdnom") :
343 self.sdnom = old_etape.sdnom
345 def get_sd_utilisees(self):
347 Retourne la liste des concepts qui sont utilisés à l'intérieur d'une commande
348 ( comme valorisation d'un MCS)
351 for child in self.mc_liste:
352 l.extend(child.get_sd_utilisees())
355 def reparent(self,parent):
357 Cette methode sert a reinitialiser la parente de l'objet
360 self.jdc=parent.get_jdc_root()
362 for mocle in self.mc_liste:
365 def get_cmd(self,nomcmd):
367 Méthode pour recuperer la definition d'une commande
368 donnee par son nom dans les catalogues declares
370 Appele par un ops d'une macro en Python
372 return self.jdc.get_cmd(nomcmd)