1 #@ MODIF N_ETAPE Noyau DATE 14/09/2004 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.
120 if not self.isactif():return
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.
196 def get_type_produit(self):
198 Retourne le type du concept résultat de l'étape
200 cas 1 : sd_prod de oper n'est pas une fonction
201 il s'agit d'une sous classe de ASSD
202 on retourne le nom de la classe
203 cas 2 : il s'agit d'une fonction
204 on l'évalue avec les mots-clés de l'étape (mc_liste)
205 et on retourne son résultat
207 if type(self.definition.sd_prod) == types.FunctionType:
208 d=self.cree_dict_valeurs(self.mc_liste)
210 sd_prod= apply(self.definition.sd_prod,(),d)
212 #traceback.print_exc()
215 sd_prod=self.definition.sd_prod
220 Retourne l'étape à laquelle appartient self
221 Un objet de la catégorie etape doit retourner self pour indiquer que
222 l'étape a été trouvée
223 XXX fait double emploi avec self.etape ????
229 Méthode qui supprime toutes les références arrières afin que l'objet puisse
230 etre correctement détruit par le garbage collector
232 N_MCCOMPO.MCCOMPO.supprime(self)
235 if self.sd : self.sd.supprime()
239 Indique si l'étape est active (1) ou inactive (0)
243 def set_current_step(self):
245 Methode utilisee pour que l etape self se declare etape
246 courante. Utilise par les macros
248 #print "set_current_step ",self.nom
249 #traceback.print_stack(limit=3,file=sys.stdout)
250 cs= CONTEXT.get_current_step()
251 if self.parent != cs :
252 raise "L'étape courante %s devrait etre le parent de self : %s" % (cs,self)
254 CONTEXT.unset_current_step()
255 CONTEXT.set_current_step(self)
257 def reset_current_step(self):
259 Methode utilisee par l'etape self qui remet son etape parent comme
262 #print "reset_current_step ",self.nom
263 #traceback.print_stack(limit=3,file=sys.stdout)
264 cs= CONTEXT.get_current_step()
266 raise "L'étape courante %s devrait etre self : %s" % (cs,self)
268 CONTEXT.unset_current_step()
269 CONTEXT.set_current_step(self.parent)
271 def issubstep(self,etape):
273 Cette methode retourne un entier indiquant si etape est une
274 sous etape de self ou non
277 Une étape simple n'a pas de sous etape
281 def get_file(self,unite=None,fic_origine=''):
283 Retourne le nom du fichier associe a l unite logique unite (entier)
284 ainsi que le source contenu dans le fichier
286 if self.jdc : return self.jdc.get_file(unite=unite,fic_origine=fic_origine)
290 if os.path.exists("fort."+str(unite)):
291 file= "fort."+str(unite)
293 raise AsException("Impossible de trouver le fichier correspondant a l unite %s" % unite)
294 if not os.path.exists(file):
295 raise AsException("%s n'est pas un fichier existant" % unite)
297 text=string.replace(fproc.read(),'\r\n','\n')
299 linecache.cache[file]=0,0,string.split(text,'\n'),file
302 def accept(self,visitor):
304 Cette methode permet de parcourir l'arborescence des objets
305 en utilisant le pattern VISITEUR
307 visitor.visitETAPE(self)
309 def update_context(self,d):
311 Cette methode doit updater le contexte fournit par
312 l'appelant en argument (d) en fonction de sa definition
314 if type(self.definition.op_init) == types.FunctionType:
315 apply(self.definition.op_init,(self,d))
317 d[self.sd.nom]=self.sd
320 """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
325 etape.state = 'modified'
330 for objet in self.mc_liste:
331 new_obj = objet.copy()
332 new_obj.reparent(etape)
333 etape.mc_liste.append(new_obj)
336 def copy_reuse(self,old_etape):
337 """ Méthode qui copie le reuse d'une autre étape.
339 if hasattr(old_etape,"reuse") :
340 self.reuse = old_etape.reuse
342 def copy_sdnom(self,old_etape):
343 """ Méthode qui copie le sdnom d'une autre étape.
345 if hasattr(old_etape,"sdnom") :
346 self.sdnom = old_etape.sdnom
348 def get_sd_utilisees(self):
350 Retourne la liste des concepts qui sont utilisés à l'intérieur d'une commande
351 ( comme valorisation d'un MCS)
354 for child in self.mc_liste:
355 l.extend(child.get_sd_utilisees())
358 def get_sd_mcs_utilisees(self):
360 Retourne la ou les SD utilisée par self sous forme d'un dictionnaire :
361 . Si aucune sd n'est utilisée, le dictionnaire est vide.
362 . Sinon, les clés du dictionnaire sont les mots-clés derrière lesquels on
363 trouve des sd ; la valeur est la liste des sd attenante.
364 Exemple : { 'VALE_F': [ <Cata.cata.para_sensi instance at 0x9419854>,
365 <Cata.cata.para_sensi instance at 0x941a204> ],
366 'MODELE': [<Cata.cata.modele instance at 0x941550c>] }
369 for child in self.mc_liste:
370 daux = child.get_sd_mcs_utilisees()
371 for cle in daux.keys():
372 dico[cle] = daux[cle]
375 def reparent(self,parent):
377 Cette methode sert a reinitialiser la parente de l'objet
380 self.jdc=parent.get_jdc_root()
382 for mocle in self.mc_liste:
385 def get_cmd(self,nomcmd):
387 Méthode pour recuperer la definition d'une commande
388 donnee par son nom dans les catalogues declares
390 Appele par un ops d'une macro en Python
392 return self.jdc.get_cmd(nomcmd)
394 def copy_intern(self,etape):
396 Méthode permettant lors du processus de recopie de copier
397 les elements internes d'une etape dans une autre
401 def full_copy(self,parent=None):
403 Méthode permettant d'effectuer une copie complète
404 d'une étape (y compris concept produit, éléments internes)
405 Si l'argument parent est fourni, la nouvelle étape
406 aura cet objet comme parent.
408 new_etape = self.copy()
409 new_etape.copy_reuse(self)
410 new_etape.copy_sdnom(self)
411 if parent: new_etape.reparent(parent)
413 new_sd = self.sd.__class__(etape=new_etape)
414 new_etape.sd = new_sd
415 if self.reuse == None :
416 new_etape.parent.NommerSdprod(new_sd,self.sd.nom)
418 new_sd.nom = self.sd.nom
419 new_etape.copy_intern(self)