1 #@ MODIF N_ETAPE Noyau DATE 10/10/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
40 from N_ASSD import ASSD
42 class ETAPE(N_MCCOMPO.MCCOMPO):
44 Cette classe hérite de MCCOMPO car ETAPE est un OBJECT composite
49 # L'attribut de classe codex est utilisé pour rattacher le module de calcul éventuel (voir Build)
50 # On le met à None pour indiquer qu'il n'y a pas de module de calcul rattaché
53 def __init__(self,oper=None,reuse=None,args={}):
57 - definition : objet portant les attributs de définition d'une étape de type opérateur. Il
58 est initialisé par l'argument oper.
60 - reuse : indique le concept d'entrée réutilisé. Il se trouvera donc en sortie
61 si les conditions d'exécution de l'opérateur l'autorise
63 - valeur : arguments d'entrée de type mot-clé=valeur. Initialisé avec l'argument args.
70 self.parent=CONTEXT.get_current_step()
73 self.idracine=oper.label
74 self.appel=N_utils.callee_where()
80 def make_register(self):
82 Initialise les attributs jdc, id, niveau et réalise les
83 enregistrements nécessaires
86 self.jdc = self.parent.get_jdc_root()
87 self.id=self.parent.register(self)
90 self.jdc = self.parent =None
96 Cette methode a pour fonction de retirer tous les arguments egaux à None
97 de la liste des arguments. Ils sont supposés non présents et donc retirés.
99 for k in self.valeur.keys():
100 if self.valeur[k] == None:del self.valeur[k]
104 Demande la construction des sous-objets et les stocke dans l'attribut
107 self.mc_liste=self.build_mc()
109 def Build_sd(self,nom):
111 Construit le concept produit de l'opérateur. Deux cas
112 peuvent se présenter :
114 - le parent n'est pas défini. Dans ce cas, l'étape prend en charge la création
115 et le nommage du concept.
117 - le parent est défini. Dans ce cas, l'étape demande au parent la création et
118 le nommage du concept.
124 sd= self.parent.create_sdprod(self,nom)
125 if type(self.definition.op_init) == types.FunctionType:
126 apply(self.definition.op_init,(self,self.parent.g_context))
128 sd=self.get_sd_prod()
129 # On n'utilise pas self.definition.op_init car self.parent
131 if sd != None and self.reuse == None:
132 # On ne nomme le concept que dans le cas de non reutilisation
135 except AsException,e:
136 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
137 'fichier : ',self.appel[1],e)
141 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
142 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
143 'fichier : ',self.appel[1]+'\n',
151 Cette methode est un point d'entree prevu pour realiser une execution immediatement
152 apres avoir construit les mots cles et le concept produit.
153 Par defaut, elle ne fait rien. Elle doit etre surchargee dans une autre partie du programme.
157 def get_sd_prod(self):
159 Retourne le concept résultat de l'étape
161 cas 1 : sd_prod de oper n'est pas une fonction
162 il s'agit d'une sous classe de ASSD
163 on construit le sd à partir de cette classe
165 cas 2 : il s'agit d'une fonction
166 on l'évalue avec les mots-clés de l'étape (mc_liste)
167 on construit le sd à partir de la classe obtenue
170 if type(self.definition.sd_prod) == types.FunctionType:
171 d=self.cree_dict_valeurs(self.mc_liste)
173 sd_prod= apply(self.definition.sd_prod,(),d)
177 if CONTEXT.debug: traceback.print_exc()
178 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],
180 raise AsException("impossible d affecter un type au resultat",
182 # sys.exc_info()[0],sys.exc_info()[1],)
184 sd_prod=self.definition.sd_prod
185 # on teste maintenant si la SD est réutilisée ou s'il faut la créer
186 if self.definition.reentrant != 'n' and self.reuse:
187 # Le concept produit est specifie reutilise (reuse=xxx). C'est une erreur mais non fatale.
188 # Elle sera traitee ulterieurement.
191 self.sd= sd_prod(etape=self)
192 # Si l'operateur est obligatoirement reentrant et reuse n'a pas ete specifie, c'est une erreur.
193 # On ne fait rien ici. L'erreur sera traiter par la suite.
195 if self.sd is not None and not isinstance(self.sd, ASSD):
196 raise AsException("""
197 Impossible de typer le résultat !
199 Utilisateur : Soit la valeur fournie derrière "reuse" est incorrecte,
200 soit il y a une "," à la fin d'une commande précédente.
201 Développeur : La fonction "sd_prod" retourne un type invalide.""")
204 def get_type_produit(self):
206 return self.get_type_produit_brut()
210 def get_type_produit_brut(self):
212 Retourne le type du concept résultat de l'étape
214 cas 1 : sd_prod de oper n'est pas une fonction
215 il s'agit d'une sous classe de ASSD
216 on retourne le nom de la classe
217 cas 2 : il s'agit d'une fonction
218 on l'évalue avec les mots-clés de l'étape (mc_liste)
219 et on retourne son résultat
221 if type(self.definition.sd_prod) == types.FunctionType:
222 d=self.cree_dict_valeurs(self.mc_liste)
223 sd_prod= apply(self.definition.sd_prod,(),d)
225 sd_prod=self.definition.sd_prod
230 Retourne l'étape à laquelle appartient self
231 Un objet de la catégorie etape doit retourner self pour indiquer que
232 l'étape a été trouvée
233 XXX fait double emploi avec self.etape ????
239 Méthode qui supprime toutes les références arrières afin que l'objet puisse
240 etre correctement détruit par le garbage collector
242 N_MCCOMPO.MCCOMPO.supprime(self)
245 if self.sd : self.sd.supprime()
249 Indique si l'étape est active (1) ou inactive (0)
253 def set_current_step(self):
255 Methode utilisee pour que l etape self se declare etape
256 courante. Utilise par les macros
258 #print "set_current_step ",self.nom
259 #traceback.print_stack(limit=3,file=sys.stdout)
260 cs= CONTEXT.get_current_step()
261 if self.parent != cs :
262 raise "L'étape courante %s devrait etre le parent de self : %s" % (cs,self)
264 CONTEXT.unset_current_step()
265 CONTEXT.set_current_step(self)
267 def reset_current_step(self):
269 Methode utilisee par l'etape self qui remet son etape parent comme
272 #print "reset_current_step ",self.nom
273 #traceback.print_stack(limit=3,file=sys.stdout)
274 cs= CONTEXT.get_current_step()
276 raise "L'étape courante %s devrait etre self : %s" % (cs,self)
278 CONTEXT.unset_current_step()
279 CONTEXT.set_current_step(self.parent)
281 def issubstep(self,etape):
283 Cette methode retourne un entier indiquant si etape est une
284 sous etape de self ou non
287 Une étape simple n'a pas de sous etape
291 def get_file(self,unite=None,fic_origine=''):
293 Retourne le nom du fichier associe a l unite logique unite (entier)
294 ainsi que le source contenu dans le fichier
296 if self.jdc : return self.jdc.get_file(unite=unite,fic_origine=fic_origine)
300 if os.path.exists("fort."+str(unite)):
301 file= "fort."+str(unite)
303 raise AsException("Impossible de trouver le fichier correspondant a l unite %s" % unite)
304 if not os.path.exists(file):
305 raise AsException("%s n'est pas un fichier existant" % unite)
307 text=string.replace(fproc.read(),'\r\n','\n')
309 linecache.cache[file]=0,0,string.split(text,'\n'),file
312 def accept(self,visitor):
314 Cette methode permet de parcourir l'arborescence des objets
315 en utilisant le pattern VISITEUR
317 visitor.visitETAPE(self)
319 def update_context(self,d):
321 Cette methode doit updater le contexte fournit par
322 l'appelant en argument (d) en fonction de sa definition
324 if type(self.definition.op_init) == types.FunctionType:
325 apply(self.definition.op_init,(self,d))
327 d[self.sd.nom]=self.sd
330 """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
335 etape.state = 'modified'
340 for objet in self.mc_liste:
341 new_obj = objet.copy()
342 new_obj.reparent(etape)
343 etape.mc_liste.append(new_obj)
346 def copy_reuse(self,old_etape):
347 """ Méthode qui copie le reuse d'une autre étape.
349 if hasattr(old_etape,"reuse") :
350 self.reuse = old_etape.reuse
352 def copy_sdnom(self,old_etape):
353 """ Méthode qui copie le sdnom d'une autre étape.
355 if hasattr(old_etape,"sdnom") :
356 self.sdnom = old_etape.sdnom
358 def reparent(self,parent):
360 Cette methode sert a reinitialiser la parente de l'objet
363 self.jdc=parent.get_jdc_root()
365 for mocle in self.mc_liste:
367 if self.sd and self.reuse == None :
370 def get_cmd(self,nomcmd):
372 Méthode pour recuperer la definition d'une commande
373 donnee par son nom dans les catalogues declares
375 Appele par un ops d'une macro en Python
377 return self.jdc.get_cmd(nomcmd)
379 def copy_intern(self,etape):
381 Méthode permettant lors du processus de recopie de copier
382 les elements internes d'une etape dans une autre
386 def full_copy(self,parent=None):
388 Méthode permettant d'effectuer une copie complète
389 d'une étape (y compris concept produit, éléments internes)
390 Si l'argument parent est fourni, la nouvelle étape
391 aura cet objet comme parent.
393 new_etape = self.copy()
394 new_etape.copy_reuse(self)
395 new_etape.copy_sdnom(self)
396 if parent: new_etape.reparent(parent)
398 new_sd = self.sd.__class__(etape=new_etape)
399 new_etape.sd = new_sd
400 if self.reuse == None :
401 new_etape.parent.NommerSdprod(new_sd,self.sd.nom)
403 new_sd.nom = self.sd.nom
404 new_etape.copy_intern(self)
407 def reset_jdc(self,new_jdc):
409 Reinitialise le nommage du concept de l'etape lors d'un changement de jdc
411 if self.sd and self.reuse == None :
412 self.parent.NommerSdprod(self.sd,self.sd.nom)