Salome HOME
correction dans Build_sd
[tools/eficas.git] / Ihm / I_MACRO_ETAPE.py
1 """
2 """
3 # Modules Python
4 import traceback,types,string
5
6 # Modules Eficas
7 import I_ETAPE
8 from Noyau.N_ASSD import ASSD
9
10 # import rajoutés suite à l'ajout de Build_sd --> à résorber
11 import Noyau
12 from Noyau import N_Exception
13 from Noyau.N_Exception import AsException
14 # fin import à résorber
15
16 class MACRO_ETAPE(I_ETAPE.ETAPE):
17
18   def __init__(self):
19       I_ETAPE.ETAPE.__init__(self)
20       # XXX CCAR : ne suis pas certain que typret doive etre 
21       # initialise à None (a verifier)
22       self.typret=None
23
24   def get_sdprods(self,nom_sd):
25     """ 
26          Fonction : retourne le concept produit par l etape de nom nom_sd
27                     s il existe sinon None
28     """
29     if self.sd:
30       if self.sd.nom == nom_sd:
31          return self.sd
32     for co in self.sdprods:
33       if co.nom==nom_sd:return co
34     return None
35
36   def make_contexte(self,fichier,text):    
37     """
38         Cette méthode sert à créer un contexte en interprétant un texte source
39         Python
40     """
41     # on récupère le contexte d'un nouveau jdc dans lequel on interprete text
42     contexte = self.get_contexte_jdc(fichier,text)
43     if contexte == None :
44       raise Exception("Impossible de relire le fichier")
45     else:
46       self.g_context = contexte
47       if hasattr(self,'contexte_fichier_init'):
48         self.old_contexte_fichier_init = self.contexte_fichier_init
49       self.contexte_fichier_init = contexte
50       # XXX la validité ne doit pas etre forcée à 1. Que faut-il faire exactement ???
51       self.init_modif()
52       #self.valid = 1
53       #self.state = 'unchanged'
54
55   def get_contexte_jdc(self,fichier,text):
56     """ 
57          Interprète text comme un texte de jdc et retourne le 
58          contexte final
59          cad le dictionnaire des sd disponibles à la dernière étape
60          Si text n'est pas un texte de jdc valide, retourne None
61          --> utilisée par ops.POURSUITE et INCLUDE
62     """
63     try:
64        # on essaie de créer un objet JDC...
65        context_ini = self.parent.get_contexte_avant(self)
66
67        CONTEXT.unset_current_step()
68        j=self.jdc.definition(procedure=text,cata=self.jdc.cata,
69                              nom=fichier,
70                              context_ini = context_ini,
71                              appli=self.jdc.appli)
72        j.analyse()
73        # XXX en passant par un jdc auxiliaire, on risque de rendre les etapes inactives
74        # on les force dans l'etat actif
75        for etape in j.etapes:
76           etape.active()
77     except:
78        traceback.print_exc()
79        return None
80     CONTEXT.set_current_step(self)
81     if not j.cr.estvide():
82         raise Exception("Impossible de relire le fichier\n"+str(j.cr))
83
84     #XXX la validité d'un source inclus n'est pas identique à celle d'un JDC complet
85     #    impossible de la tester en dehors du JDC d'accueil
86     #cr=j.report()
87     #if not cr.estvide():
88     #    raise Exception("Le fichier contient des erreurs\n"+str(j.cr))
89     j_context=j.get_contexte_avant(None)
90     # XXX j.g_context doit donner le meme résultat
91     # On retourne le contexte apres la derniere etape
92     # XXX j.supprime() ???
93     self.verif_contexte(j_context)
94     # Le contexte est acceptable. On récupère les étapes internes (pour validation)
95     self.etapes=j.etapes
96     return j_context
97
98   def verif_contexte(self,context):
99      """
100          On verifie que le contexte context peut etre inséré dans le jeu
101          de commandes à la position de self
102      """
103      for nom_sd,sd in context.items():
104         if not isinstance(sd,ASSD):continue
105         if self.parent.get_sd_apres_etape(nom_sd,etape=self):
106            # Il existe un concept apres self => impossible d'inserer
107            raise Exception("Impossible d'inclure le fichier. Un concept de nom " + 
108                            "%s existe déjà dans le jeu de commandes." % nom_sd)
109
110   def reevalue_sd_jdc(self):
111      """
112          Avec la liste des SD qui ont été supprimées, propage la 
113          disparition de ces SD dans totues les étapes et descendants
114      """
115      l_sd = self.diff_contextes()
116      if len(l_sd) == 0 : return
117      for sd in l_sd:
118         self.jdc.delete_concept(sd)
119
120   def diff_contextes(self):
121      """ 
122          Réalise la différence entre les 2 contextes 
123          old_contexte_fichier_init et contexte_fichier_init
124          cad retourne la liste des sd qui ont disparu 
125      """
126      if not hasattr(self,'old_contexte_fichier_init'):return []
127      l_sd_suppressed = []
128      for old_key in self.old_contexte_fichier_init.keys():
129        if not self.contexte_fichier_init.has_key(old_key):
130          if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
131            l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
132      return l_sd_suppressed
133       
134   def supprime_sdprods(self):
135       """
136           Fonction:
137             Lors d'une destruction d'etape, detruit tous les concepts produits
138             Un opérateur n a qu un concept produit
139             Une procedure n'en a aucun
140             Une macro en a en général plus d'un
141       """
142       if not self.is_reentrant() :
143          # l'étape n'est pas réentrante
144          # le concept retourné par l'étape est à supprimer car il était
145          # créé par l'étape
146          if self.sd != None :
147             self.parent.del_sdprod(self.sd)
148             self.parent.delete_concept(self.sd)
149       # On détruit les concepts à droite du signe =
150       for co in self.sdprods:
151          self.parent.del_sdprod(co)
152          self.parent.delete_concept(co)
153       # Si la macro a des etapes et des concepts inclus, on les detruit
154       for nom_sd,co in self.g_context.items():
155          if not isinstance(co,ASSD):continue
156          print "Delete: ",self.nom,co.nom
157          self.parent.del_sdprod(co)
158          self.parent.delete_concept(co)
159       # On met g_context à blanc
160       self.g_context={}
161          
162   def Build_sd(self,nom):
163      """
164         Construit le concept produit de l'opérateur. Deux cas 
165         peuvent se présenter :
166
167         - le parent n'est pas défini. Dans ce cas, l'étape prend en charge 
168           la création et le nommage du concept.
169
170         - le parent est défini. Dans ce cas, l'étape demande au parent la 
171           création et le nommage du concept.
172
173      """
174      if not self.isactif():return
175      # CCAR : meme modification que dans I_ETAPE
176      if not self.isvalid(sd='non') : return
177      else:self.state='undetermined'
178      try:
179         # On positionne la macro self en tant que current_step pour que les 
180         # étapes créées lors de l'appel à sd_prod et à op_init aient la macro
181         #  comme parent 
182         self.set_current_step()
183         if self.parent:
184            sd= self.parent.create_sdprod(self,nom)
185            if type(self.definition.op_init) == types.FunctionType: 
186               apply(self.definition.op_init,(self,self.parent.g_context))
187         else:
188            sd=self.get_sd_prod()
189            if sd != None and self.reuse == None:
190               # On ne nomme le concept que dans le cas de non reutilisation 
191               # d un concept
192               sd.nom=nom
193         self.reset_current_step()
194         if self.jdc and self.jdc.par_lot == "NON" :
195            self.Execute()
196         return sd
197      except AsException,e:
198         self.reset_current_step()
199         raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
200                              'fichier : ',self.appel[1],e)
201      except EOFError:
202         #self.reset_current_step()
203         raise
204      except :
205         self.reset_current_step()
206         l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
207         raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
208                           'fichier : ',self.appel[1]+'\n',
209                            string.join(l))