]> SALOME platform Git repositories - tools/eficas.git/blob - Ihm/I_MACRO_ETAPE.py
Salome HOME
pour elts de structure
[tools/eficas.git] / Ihm / I_MACRO_ETAPE.py
1 # -*- coding: utf-8 -*-
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.
9 #
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.
14 #
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.
18 #
19 #
20 # ======================================================================
21 """
22 """
23 # Modules Python
24 import sys
25 import traceback,types,string
26
27 # Modules Eficas
28 import I_ETAPE
29 from Noyau.N_ASSD import ASSD
30
31 # import rajoutés suite à l'ajout de Build_sd --> à résorber
32 import Noyau, Validation.V_MACRO_ETAPE
33 from Noyau import N_Exception
34 from Noyau.N_Exception import AsException
35 import Accas # attention aux imports circulaires
36 # fin import à résorber
37
38 class MACRO_ETAPE(I_ETAPE.ETAPE):
39
40   def __init__(self):
41       self.typret=None
42       self.recorded_units={}
43
44   def get_sdprods(self,nom_sd):
45     """ 
46          Fonction : retourne le concept produit par l etape de nom nom_sd
47          s il existe sinon None
48     """
49     if self.sd and self.sd.nom == nom_sd :return self.sd
50     for co in self.sdprods:
51       if co.nom == nom_sd:return co
52     if type(self.definition.op_init) == types.FunctionType:
53       d={}
54       apply(self.definition.op_init,(self,d))
55       return d.get(nom_sd,None)
56     return None
57
58   def get_contexte_jdc(self,fichier,text):
59     """ 
60          Interprète text comme un texte de jdc et retourne le 
61          contexte final
62          cad le dictionnaire des sd disponibles à la dernière étape
63          Si text n'est pas un texte de jdc valide, retourne None
64          ou leve une exception
65          --> utilisée par ops.POURSUITE et INCLUDE
66     """
67     #print "get_contexte_jdc",self,self.nom
68     try:
69        # on essaie de créer un objet JDC auxiliaire avec un contexte initial
70        # Attention get_contexte_avant retourne un dictionnaire qui contient
71        # le contexte courant. Ce dictionnaire est reactualise regulierement.
72        # Si on veut garder l'etat du contexte fige, il faut en faire une copie.
73        context_ini = self.parent.get_contexte_avant(self).copy()
74        #print "get_contexte_jdc",context_ini.keys()
75
76        # Indispensable avant de creer un nouveau JDC
77        CONTEXT.unset_current_step()
78        args=self.jdc.args
79        prefix_include=None
80        if hasattr(self,'prefix'):
81           prefix_include=self.prefix
82        # ATTENTION : le dictionnaire recorded_units sert à memoriser les unites des 
83        # fichiers inclus. Il est preferable de garder le meme dictionnaire pendant
84        # tout le traitement et de ne pas le reinitialiser brutalement (utiliser 
85        # clear plutot) si on ne veut pas perdre la memoire des unites.
86        # En principe si la memorisation est faite au bon moment il n'est pas necessaire
87        # de prendre cette precaution mais ce n'est pas vrai partout.
88        old_recorded_units=self.recorded_units.copy()
89
90        if fichier is None:fichier="SansNom"
91        j=self.JdC_aux( procedure=text, nom=fichier,
92                                 appli=self.jdc.appli,
93                                 cata=self.jdc.cata,
94                                 cata_ord_dico=self.jdc.cata_ordonne_dico,
95                                 context_ini = context_ini,
96                                 jdc_pere=self.jdc,etape_include=self,
97                                 prefix_include=prefix_include,
98                                 recorded_units=self.recorded_units,
99                                 old_recorded_units=old_recorded_units,**args)
100
101        j.analyse()
102        # On récupère les étapes internes (pour validation)
103        self.etapes=j.etapes
104        self.jdc_aux=j
105     except:
106        # On force le contexte (etape courante) à self
107        CONTEXT.unset_current_step()
108        CONTEXT.set_current_step(self)
109        return None
110
111     if not j.cr.estvide():
112        # Erreurs dans l'INCLUDE. On garde la memoire du fichier 
113        # mais on n'insere pas les concepts
114        # On force le contexte (etape courante) à self
115        CONTEXT.unset_current_step()
116        CONTEXT.set_current_step(self)
117        raise Exception("Impossible de relire le fichier\n"+str(j.cr))
118
119     if not j.isvalid():
120        # L'INCLUDE n'est pas valide.
121        # on produit un rapport d'erreurs
122        # On force le contexte (etape courante) à self
123        cr=j.report()
124        CONTEXT.unset_current_step()
125        CONTEXT.set_current_step(self)
126        raise Exception("Le fichier include contient des erreurs\n"+str(cr))
127
128     # Si aucune erreur rencontrée
129     # On recupere le contexte de l'include verifie
130     try:
131        j_context=j.get_verif_contexte()
132     except:
133        CONTEXT.unset_current_step()
134        CONTEXT.set_current_step(self)
135        raise
136
137     # On remplit le dictionnaire des concepts produits inclus
138     # en retirant les concepts présents dans le  contexte initial
139     # On ajoute egalement le concept produit dans le sds_dict du parent
140     # sans verification car on est sur (verification integrée) que 
141     # le nommage est possible
142     self.g_context.clear()
143     for k,v in j_context.items():
144        if not context_ini.has_key(k) or context_ini[k] != v:
145            self.g_context[k]=v
146            self.parent.sds_dict[k]=v
147
148
149     # On recupere le contexte courant
150     self.current_context=j.current_context
151     self.index_etape_courante=j.index_etape_courante
152     self.jdc_aux=j
153
154     # On rétablit le contexte (etape courante) à self
155     CONTEXT.unset_current_step()
156     CONTEXT.set_current_step(self)
157
158     return j_context
159
160   def reevalue_sd_jdc(self):
161      """
162          Avec la liste des SD qui ont été supprimées, propage la 
163          disparition de ces SD dans toutes les étapes et descendants
164      """
165      #print "reevalue_sd_jdc"
166      l_sd_supp,l_sd_repl = self.diff_contextes()
167      for sd in l_sd_supp:
168         self.parent.delete_concept_after_etape(self,sd)
169      for old_sd,sd in l_sd_repl:
170         self.parent.replace_concept_after_etape(self,old_sd,sd)
171
172   def diff_contextes(self):
173      """ 
174          Réalise la différence entre les 2 contextes 
175          old_contexte_fichier_init et contexte_fichier_init
176          cad retourne la liste des sd qui ont disparu ou ne derivent pas 
177          de la meme classe et des sd qui ont ete remplacees
178      """
179      if not hasattr(self,'old_contexte_fichier_init'):return [],[]
180      l_sd_suppressed = []
181      l_sd_replaced = []
182      for old_key in self.old_contexte_fichier_init.keys():
183        if not self.contexte_fichier_init.has_key(old_key):
184          if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
185            l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
186        else:
187          if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
188             # Un concept de meme nom existe
189             old_class=self.old_contexte_fichier_init[old_key].__class__
190             if not isinstance(self.contexte_fichier_init[old_key],old_class):
191                # S'il n'est pas d'une classe derivee, on le supprime
192                l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
193             else:
194                l_sd_replaced.append((self.old_contexte_fichier_init[old_key],self.contexte_fichier_init[old_key]))
195      return l_sd_suppressed,l_sd_replaced
196       
197   def control_sdprods(self,d):
198       """
199           Cette methode doit verifier que les concepts produits par la 
200           commande ne sont pas incompatibles avec le contexte fourni (d).
201           Si c'est le cas, le concept produit doit etre supprime
202           Si la macro a elle meme des etapes, elle doit propager
203           le traitement (voir methode control_jdc_context_apres de I_JDC)
204       """
205       #print "I_MACRO_ETAPE.control_sdprods",d.keys(),self.nom,self.sd and self.sd.nom
206       if self.sd:
207         if d.has_key(self.sd.nom):
208            # Le concept est deja defini
209            if self.reuse and self.reuse is d[self.sd.nom]:
210               # Le concept est reutilise : situation normale
211               pass
212            else:
213               # Redefinition du concept, on l'annule
214               #XXX on pourrait simplement annuler son nom pour conserver les objets
215               # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
216               self.init_modif()
217               sd=self.sd
218               self.sd=self.reuse=self.sdnom=None
219               self.parent.delete_concept_after_etape(self,sd)
220               self.fin_modif()
221
222       # On verifie les concepts a droite du signe =
223       self.init_modif()
224       sdprods=self.sdprods[:]
225       self.sdprods=[]
226       for co in sdprods:
227         if d.has_key(co.nom) and co is not d[co.nom] :
228            #nettoie les mots cles de l'étape qui ont comme valeur co
229            self.delete_concept(co)
230            #supprime les references a co dans les etapes suivantes
231            self.parent.delete_concept_after_etape(self,co)
232         else:
233            self.sdprods.append(co)
234       self.fin_modif()
235        
236       for e in self.etapes:
237           e.control_sdprods(d)
238           e.update_context(d)
239
240   def supprime_sdprod(self,sd):
241       """
242          Supprime le concept produit sd s'il est produit par l'etape
243       """
244       if sd in self.sdprods:
245          self.init_modif()
246          self.parent.del_sdprod(sd)
247          self.sdprods.remove(sd)
248          self.fin_modif()
249          self.parent.delete_concept(sd)
250          return
251
252       if sd is not self.sd :return
253       if self.sd is not None :
254          self.init_modif()
255          self.parent.del_sdprod(sd)
256          self.sd=None
257          self.fin_modif()
258          self.parent.delete_concept(sd)
259
260   def supprime_sdprods(self):
261       """
262           Fonction: Lors de la destruction de la macro-etape, detruit tous les concepts produits
263           Un opérateur n a qu un concept produit
264           Une procedure n'en a aucun
265           Une macro en a en général plus d'un
266       """
267       #print "supprime_sdprods"
268       if self.reuse is not self.sd :
269          # l'étape n'est pas réentrante
270          # le concept retourné par l'étape est à supprimer car il était
271          # créé par l'étape
272          if self.sd != None :
273             self.parent.del_sdprod(self.sd)
274             self.parent.delete_concept(self.sd)
275       # On détruit les concepts à droite du signe =
276       for co in self.sdprods:
277          self.parent.del_sdprod(co)
278          self.parent.delete_concept(co)
279       # Si la macro a des etapes et des concepts inclus, on les detruit
280       for nom_sd,co in self.g_context.items():
281          if not isinstance(co,ASSD):continue
282          self.parent.del_sdprod(co)
283          self.parent.delete_concept(co)
284       # On met g_context à blanc
285       self.g_context={}
286
287   def close(self):
288       if hasattr(self,"jdc_aux") and self.jdc_aux:
289          # La macro a un jdc auxiliaire inclus. On demande sa fermeture
290          self.jdc_aux.close()
291
292   def reset_context(self):
293       if hasattr(self,"jdc_aux") and self.jdc_aux:
294          # La macro a un jdc auxiliaire inclus. On demande la reinitialisation du contexte
295          self.jdc_aux.reset_context()
296
297   def update_concept(self,sd):
298       I_ETAPE.ETAPE.update_concept(self,sd)
299       for etape in self.etapes:
300           etape.update_concept(sd)
301
302   def delete_concept(self,sd):
303       """
304           Fonction : Mettre a jour les mots cles de l etape et eventuellement
305           le concept produit si reuse suite à la disparition du concept sd
306           Seuls les mots cles simples MCSIMP font un traitement autre
307           que de transmettre aux fils
308       """
309       #print "delete_concept",sd
310       I_ETAPE.ETAPE.delete_concept(self,sd)
311       for etape in self.etapes:
312          etape.delete_concept(sd)
313
314   def replace_concept(self,old_sd,sd):
315       """
316           Fonction : Mettre a jour les mots cles de l etape et le concept produit si reuse 
317           suite au remplacement  du concept old_sd par sd
318       """
319       #print "replace_concept",old_sd,sd
320       I_ETAPE.ETAPE.replace_concept(self,old_sd,sd)
321       for etape in self.etapes:
322          etape.replace_concept(old_sd,sd)
323          
324   def change_fichier_init(self,new_fic,text):
325     """
326        Tente de changer le fichier include. Le precedent include est conservé
327        dans old_xxx
328     """
329     #print "change_fichier_init",new_fic
330     if not hasattr(self,'fichier_ini'):
331        self.fichier_ini=None
332        self.fichier_text=None
333        self.fichier_err="Le fichier n'est pas defini"
334        self.contexte_fichier_init={}
335        self.recorded_units={}
336        self.jdc_aux=None
337        self.fichier_unite="PasDefini"
338        import Extensions.jdc_include
339        self.JdC_aux=Extensions.jdc_include.JdC_include
340
341     self.old_fic = self.fichier_ini
342     self.old_text = self.fichier_text
343     self.old_err = self.fichier_err
344     self.old_context=self.contexte_fichier_init
345     self.old_units=self.recorded_units
346     self.old_etapes=self.etapes
347     self.old_jdc_aux=self.jdc_aux
348
349     self.fichier_ini = new_fic
350     self.fichier_text=text
351
352     try:
353        self.make_contexte_include(new_fic,text)
354     except:
355        l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
356        self.fichier_err=string.join(l)
357        raise
358
359     # L'evaluation de text dans un JDC auxiliaire s'est bien passé
360     # on peut poursuivre le traitement
361     self.init_modif()
362     self.state="undetermined"
363     self.fichier_err=None
364     # On enregistre la modification de fichier
365     self.record_unite()
366     # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
367     self.parent.reset_context()
368
369     # Si des concepts ont disparu lors du changement de fichier, on demande leur suppression
370     self.old_contexte_fichier_init=self.old_context
371     self.reevalue_sd_jdc()
372
373     self.fin_modif()
374     if self.old_jdc_aux:
375        self.old_jdc_aux.close()
376
377   def restore_fichier_init(self):
378     """
379        Restaure le fichier init enregistre dans old_xxx
380     """
381     self.fichier_ini=self.old_fic
382     self.fichier_text=self.old_text
383     self.fichier_err=self.old_err
384     self.contexte_fichier_init=self.old_context
385     self.recorded_units=self.old_units
386     self.etapes=self.old_etapes
387     self.jdc_aux=self.old_jdc_aux
388
389   def force_fichier_init(self):
390     """
391        Force le remplacement du fichier init meme si le remplacant est en erreur
392     """
393     # Reinitialisation complete du compte-rendu d'erreurs
394     self.jdc_aux.cr=self.jdc_aux.CR()
395     # On remplit le dictionnaire des concepts produits inclus
396     # en retirant les concepts présents dans le  contexte initial
397     # On ajoute egalement le concept produit dans le sds_dict du parent
398     # sans verification car on est sur (verification integrée) que
399     # le nommage est possible
400     j_context=self.jdc_aux.get_contexte_avant(None)
401     self.g_context.clear()
402     context_ini=self.jdc_aux.context_ini
403     for k,v in j_context.items():
404        if not context_ini.has_key(k) or context_ini[k] != v:
405            self.g_context[k]=v
406            self.parent.sds_dict[k]=v
407     # On recupere le contexte courant
408     self.current_context=self.jdc_aux.current_context
409     self.index_etape_courante=self.jdc_aux.index_etape_courante
410     self.contexte_fichier_init = j_context
411     self.fichier_err = None
412
413     # On enregistre la modification de fichier
414     self.init_modif()
415     self.state="undetermined"
416     self.record_unite()
417     # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
418     self.parent.reset_context()
419
420     # On remplace les anciens concepts par les nouveaux (y compris ajouts 
421     # et suppression) et on propage les modifications aux etapes precedentes et suivantes
422     # reevalue_sd_jdc construit la liste des differences entre les contextes contexte_fichier_init
423     # et old_contexte_fichier_init et effectue les destructions et remplacements de concept
424     # necessaires
425     self.old_contexte_fichier_init=self.old_context
426     self.reevalue_sd_jdc()
427     self.fin_modif()
428     if self.old_jdc_aux:
429        self.old_jdc_aux.close()
430
431     self.jdc_aux.force_contexte(self.g_context)
432
433   def build_include(self,fichier,text):
434     import Extensions.jdc_include
435     self.JdC_aux=Extensions.jdc_include.JdC_include
436     # un include partage la table des unites avec son parent (jdc)
437     self.recorded_units=self.parent.recorded_units
438     self.build_jdcaux(fichier,text)
439
440   def build_poursuite(self,fichier,text):
441     import Extensions.jdc_include
442     self.JdC_aux=Extensions.jdc_include.JdC_poursuite
443     # une poursuite a sa propre table d'unites
444     self.recorded_units={}
445     self.build_jdcaux(fichier,text)
446
447   def build_jdcaux(self,fichier,text):
448     """
449          Cree un jdc auxiliaire initialise avec text. 
450          Initialise le nom du fichier associé avec fichier
451          N'enregistre pas d'association unite <-> fichier
452     """
453     self.fichier_ini = fichier
454     self.fichier_text= text
455     self.fichier_unite=None
456     self.fichier_err = None
457     try:
458        contexte = self.get_contexte_jdc(fichier,text)
459        if contexte is None :
460           # Impossible de construire le jdc auxiliaire (sortie par None)
461           # On simule une sortie par exception
462           raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
463        else:
464           # La construction du jdc auxiliaire est allée au bout
465           self.contexte_fichier_init = contexte
466        self.init_modif()
467        self.fin_modif()
468     except:
469        # Impossible de construire le jdc auxiliaire (sortie par exception)
470        l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
471        if self.jdc.appli:
472           self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
473                                         message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
474                                        )
475        self.g_context={}
476        self.etapes=[]
477        self.jdc_aux=None
478        self.fichier_err = string.join(l)
479        self.contexte_fichier_init={}
480        self.init_modif()
481        self.fin_modif()
482        raise
483
484   def make_contexte_include(self,fichier,text):
485     """
486         Cette méthode sert à créer un contexte en interprétant un texte source
487         Python
488     """
489     #print "make_contexte_include"
490     # on récupère le contexte d'un nouveau jdc dans lequel on interprete text
491     contexte = self.get_contexte_jdc(fichier,text)
492     if contexte == None :
493       raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
494     else:
495       # Pour les macros de type include : INCLUDE, INCLUDE_MATERIAU et POURSUITE
496       # l'attribut g_context est un dictionnaire qui contient les concepts produits par inclusion
497       # l'attribut contexte_fichier_init est un dictionnaire qui contient les concepts produits
498       # en sortie de macro. g_context est obtenu en retirant de contexte_fichier_init les concepts
499       # existants en debut de macro contenus dans context_ini (dans get_contexte_jdc)
500       # g_context est utilisé pour avoir les concepts produits par la macro
501       # contexte_fichier_init est utilisé pour avoir les concepts supprimés par la macro
502       self.contexte_fichier_init = contexte
503
504   def reevalue_fichier_init_OBSOLETE(self):
505       """Recalcule les concepts produits par le fichier enregistre"""
506       #print "reevalue_fichier_init"
507       old_context=self.contexte_fichier_init
508       try:
509          self.make_contexte_include(self.fichier_ini ,self.fichier_text)
510       except:
511          l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
512          self.fichier_err = string.join(l)
513          self.g_context={}
514          self.etapes=[]
515          self.jdc_aux=None
516          self.old_contexte_fichier_init=old_context
517          self.contexte_fichier_init={}
518          self.reevalue_sd_jdc()
519          return
520
521       # L'evaluation s'est bien passee
522       self.fichier_err = None
523       self.old_contexte_fichier_init=old_context
524       self.reevalue_sd_jdc()
525
526   def update_fichier_init(self,unite):
527       """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur 
528          les noms des fichiers
529          Ceci suppose que les relations entre unites et noms ont été memorisees préalablement
530          L'include a été initialisé précédemment. Le jdc auxiliaire existe.
531       """
532       #print "update_fichier_init",unite,self.fichier_unite 
533       self.old_contexte_fichier_init=self.contexte_fichier_init
534       old_fichier_ini=self.fichier_ini
535       if not hasattr(self,"jdc_aux"):self.jdc_aux=None
536       old_jdc_aux=self.jdc_aux
537
538       #print "update_fichier_init",self,self.parent,self.parent.recorded_units
539
540       if self.fichier_unite is None:
541          # L'unité n'était pas définie précédemment. On ne change que l'unite
542          #print "update_fichier_init","pas de changement dans include"
543          self.fichier_unite=unite
544          return
545       elif unite == self.fichier_unite :
546          # L'unité n'a pas changé
547          #print "update_fichier_init","pas de changement dans include 3"
548          return
549       elif unite != self.fichier_unite :
550          # L'unité était définie précédemment. On remplace l'include 
551          #
552          f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
553          if f is None:
554             # Le fichier associé n'a pas pu etre defini
555             # on change l'unite associée mais pas l'include
556             #print "update_fichier_init","pas de changement dans include 2"
557             self.fichier_unite=unite
558             return
559          else:
560             self.fichier_ini = f
561             self.fichier_text=text
562             self.fichier_unite=unite
563          #print "update_fichier_init",self.recorded_units
564
565       #print "update_fichier_init",self.fichier_ini,self.fichier_text,self.fichier_unite
566
567       if old_fichier_ini == self.fichier_ini:
568          # Le fichier inclus n'a pas changé. On ne recrée pas le contexte
569          # mais on enregistre le changement d'association unite <-> fichier
570          #print "update_fichier_init.fichier inchange",self.jdc_aux.context_ini
571          self.parent.record_unit(unite,self)
572          return
573
574       try:
575         self.fichier_err=None
576         self.make_contexte_include(self.fichier_ini,self.fichier_text)
577         # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects
578         # avant d'appeler change_unit
579       except:
580         # Erreurs lors de l'evaluation de text dans un JDC auxiliaire
581         l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
582         # On conserve la memoire du nouveau fichier
583         # mais on n'utilise pas les concepts crees par ce fichier
584         # on met l'etape en erreur : fichier_err=string.join(l)
585         self.fichier_err=string.join(l)
586         self.g_context={}
587         self.etapes=[]
588         self.jdc_aux=None
589         self.contexte_fichier_init={}
590
591       if old_jdc_aux:
592          old_jdc_aux.close()
593       self.parent.record_unit(unite,self)
594       # Le contexte du parent doit etre reinitialise car les concepts 
595       # produits ont changé
596       self.parent.reset_context()
597       # Si des concepts ont disparu lors du changement de fichier, on 
598       # demande leur suppression
599       self.reevalue_sd_jdc()
600       #print "update_fichier_init",self.jdc_aux.context_ini.keys()
601
602   def record_unite(self):
603       #print "record_unite",self.nom
604       if self.nom == "POURSUITE":
605          self.parent.record_unit(None,self)
606       else:
607          if hasattr(self,'fichier_unite') : 
608             self.parent.record_unit(self.fichier_unite,self)
609
610   def get_file_memo(self,unite=None,fic_origine=''):
611       """Retourne le nom du fichier et le source correspondant a l'unite unite
612          Initialise en plus recorded_units
613       """
614       #print "get_file_memo",unite,fic_origine,self,self.parent
615       #print self.parent.recorded_units
616       if unite is None:
617          # On est dans le cas d'une poursuite. On ne reutilise aucune unite de parent
618          units={}
619       else:
620          # On est dans le cas d'un include. On reutilise toutes les unites de parent
621          units=self.parent.recorded_units
622
623       if self.parent.recorded_units.has_key(unite):
624          f,text,units=self.parent.recorded_units[unite]
625       elif self.jdc :
626          f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
627       else:
628          f,text=None,None
629
630       self.recorded_units=units
631       if f is None and self.jdc.appli:
632          self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
633                           message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
634       return f,text
635
636   def update_context(self,d):
637       """
638          Met à jour le contexte contenu dans le dictionnaire d
639          Une MACRO_ETAPE peut ajouter plusieurs concepts dans le contexte
640          Une fonction enregistree dans op_init peut egalement modifier le contexte
641       """
642       #print "update_context",self,self.nom,d.keys()
643       if hasattr(self,"jdc_aux") and self.jdc_aux:
644             #ATTENTION: update_context NE DOIT PAS appeler reset_context
645             # car il appelle directement ou indirectement update_context
646             # equivalent a reset_context. Evite les recursions
647             self.jdc_aux.context_ini=d.copy()
648             self.jdc_aux.current_context={}
649             self.jdc_aux.index_etape_courante=0
650             #ATTENTION: il ne faut pas utiliser self.jdc_aux.get_contexte_avant
651             #car cet appel conduit a des remontées multiples incohérentes dans le
652             # ou les parents. 
653             #get_context_avant appelle update_context qui NE DOIT PAS appeler get_contexte_avant
654             #On n'a besoin que d'un update local connaissant
655             # le contexte amont : d qui sert a reinitialiser self.context_ini
656             for e in self.etapes:
657                 e.update_context(d)
658             return
659
660       if type(self.definition.op_init) == types.FunctionType:
661         apply(self.definition.op_init,(self,d))
662       if self.sd != None:d[self.sd.nom]=self.sd
663       for co in self.sdprods:
664         d[co.nom]=co
665       #print "update_context.fin",d.keys()
666
667 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
668   def get_file(self,unite=None,fic_origine=''):
669       """Retourne le nom du fichier et le source correspondant a l'unite unite
670       """
671       if self.jdc :
672          f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
673       else:
674          f,text=None,None
675       return f,text
676
677 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
678   def make_include(self,unite=None):
679       """
680           Inclut un fichier dont l'unite logique est unite
681           Cette methode est appelee par la fonction sd_prod de la macro INCLUDE
682           Si l'INCLUDE est invalide, la methode doit produire une exception 
683           Sinon on retourne None. Les concepts produits par l'INCLUDE sont
684           pris en compte par le JDC parent lors du calcul du contexte (appel de ???)
685       """
686       #print "make_include",unite
687       # On supprime l'attribut unite qui bloque l'evaluation du source de l'INCLUDE
688       # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
689       del self.unite
690       # Si unite n'a pas de valeur, l'etape est forcement invalide. On peut retourner None
691       if not unite : return
692
693       if not hasattr(self,'fichier_ini') : 
694          # Si le fichier n'est pas defini on le demande
695          f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
696          # On memorise le fichier retourne
697          self.fichier_ini  = f
698          self.fichier_text = text
699          self.contexte_fichier_init={}
700          self.fichier_unite=unite
701          self.fichier_err=None
702          try:
703            import Extensions.jdc_include
704          except:
705            traceback.print_exc()
706            raise
707          self.JdC_aux=Extensions.jdc_include.JdC_include
708
709          #print "make_include",self.fichier_ini,self.fichier_text 
710          if f is None and not text:
711              self.fichier_err="Le fichier INCLUDE n est pas defini"
712              self.parent.record_unit(unite,self)
713              raise Exception(self.fichier_err)
714
715          try:
716            self.make_contexte_include(self.fichier_ini ,self.fichier_text)
717            self.parent.record_unit(unite,self)
718            #print "make_include.context_ini",self.jdc_aux.context_ini
719          except:
720            l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
721            if self.jdc.appli:
722               self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
723                                             message="Le contenu de ce fichier ne sera pas pris en compte\n"+string.join(l)
724                                            )
725            self.parent.record_unit(unite,self)
726            self.g_context={}
727            self.etapes=[]
728            self.jdc_aux=None
729            self.fichier_err = string.join(l)
730            self.contexte_fichier_init={}
731            raise
732
733       else:
734          # Si le fichier est deja defini on ne reevalue pas le fichier
735          # et on leve une exception si une erreur a été enregistrée
736          self.update_fichier_init(unite)
737          self.fichier_unite=unite
738          if self.fichier_err is not None: raise Exception(self.fichier_err)
739         
740
741 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
742   def make_contexte(self,fichier,text):
743     """
744         Cette méthode sert à créer un contexte pour INCLUDE_MATERIAU
745         en interprétant un texte source Python
746         Elle est appelee par la fonction sd_prd d'INCLUDE_MATERIAU
747     """
748     # On supprime l'attribut mat qui bloque l'evaluation du source de l'INCLUDE_MATERIAU
749     # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
750     if hasattr(self,'mat'):del self.mat
751     self.fichier_ini =fichier
752     self.fichier_unite =fichier
753     self.fichier_text=text
754     self.fichier_err=None 
755     self.contexte_fichier_init={}
756     # On specifie la classe a utiliser pour le JDC auxiliaire
757     try:
758       import Extensions.jdc_include
759     except:
760       traceback.print_exc()
761       raise
762     self.JdC_aux=Extensions.jdc_include.JdC_include
763     try:
764        self.make_contexte_include(self.fichier_ini ,self.fichier_text)
765        #self.parent.record_unit(self.fichier_unite,self)
766     except:
767        l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
768        self.fichier_err = string.join(l)
769        #self.parent.record_unit(self.fichier_unite,self)
770        self.g_context={}
771        self.etapes=[]
772        self.jdc_aux=None
773        self.contexte_fichier_init={}
774        raise
775
776 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
777   def update_sdprod(self,cr='non'):
778      # Cette methode peut etre appelee dans EFICAS avec des mots cles de 
779      # la commande modifies. Ceci peut conduire a la construction ou
780      # a la reconstruction d'etapes dans le cas d'INCLUDE ou d'INCLUDE_MATERIAU
781      # Il faut donc positionner le current_step avant l'appel
782      CONTEXT.unset_current_step()
783      CONTEXT.set_current_step(self)
784      valid=Validation.V_MACRO_ETAPE.MACRO_ETAPE.update_sdprod(self,cr=cr)
785      CONTEXT.unset_current_step()
786      return valid
787
788 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro 
789   def Build_sd(self,nom):
790       """
791            Methode de Noyau surchargee pour poursuivre malgre tout
792            si une erreur se produit pendant la creation du concept produit
793       """
794       try:
795          sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom)
796       except AsException,e:
797          # Une erreur s'est produite lors de la construction du concept
798          # Comme on est dans EFICAS, on essaie de poursuivre quand meme
799          # Si on poursuit, on a le choix entre deux possibilités :
800          # 1. on annule la sd associée à self
801          # 2. on la conserve mais il faut la retourner
802          # On choisit de l'annuler
803          # En plus il faut rendre coherents sdnom et sd.nom
804          self.sd=None
805          self.sdnom=None
806          self.state="unchanged"
807          self.valid=0
808
809       return self.sd
810
811 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro 
812   def make_poursuite(self):
813       """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE
814       """
815       #print "make_poursuite"
816       if not hasattr(self,'fichier_ini') :
817          # Si le fichier n'est pas defini on le demande
818          f,text=self.get_file_memo(fic_origine=self.parent.nom)
819          # On memorise le fichier retourne
820          self.fichier_ini = f
821          self.fichier_unite = None
822          self.fichier_text = text
823          self.fichier_err=None
824          try:
825            import Extensions.jdc_include
826          except:
827            traceback.print_exc()
828            raise
829          self.JdC_aux=Extensions.jdc_include.JdC_poursuite
830          self.contexte_fichier_init={}
831          #print "make_poursuite",self.fichier_ini,self.fichier_text
832
833          if f is None:
834              self.fichier_err="Le fichier POURSUITE n'est pas defini"
835              self.jdc_aux=None
836              self.parent.record_unit(None,self)
837              raise Exception(self.fichier_err)
838
839          try:
840            self.make_contexte_include(self.fichier_ini,self.fichier_text)
841            self.parent.record_unit(None,self)
842          except:
843            l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
844            if self.jdc.appli:
845               self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier poursuite",
846                                             message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
847                                            )
848            self.parent.record_unit(None,self)
849            self.g_context={}
850            self.etapes=[]
851            self.jdc_aux=None
852            self.fichier_err = string.join(l)
853            self.contexte_fichier_init={}
854            raise
855
856       else:
857          # Si le fichier est deja defini on ne reevalue pas le fichier
858          # et on leve une exception si une erreur a été enregistrée
859          self.update_fichier_init(None)
860          if self.fichier_err is not None: raise Exception(self.fichier_err)