Salome HOME
debug intempestif
[tools/eficas.git] / Validation / V_MACRO_ETAPE.py
1 # coding=utf-8
2 # person_in_charge: mathieu.courtois at edf.fr
3 # ======================================================================
4 # COPYRIGHT (C) 2007-2021  EDF R&D                  
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 """
24    Ce module contient la classe mixin MACRO_ETAPE qui porte les methodes
25    necessaires pour realiser la validation d'un objet de type MACRO_ETAPE
26    derive de OBJECT.
27
28    Une classe mixin porte principalement des traitements et est
29    utilisee par heritage multiple pour composer les traitements.
30 """
31 from __future__ import print_function
32 from __future__ import absolute_import
33 # Modules Python
34 import types
35 import sys
36 import traceback
37
38 # Modules EFICAS
39 from . import V_MCCOMPO
40 from . import V_ETAPE
41 from Noyau.N_Exception import AsException
42 from Noyau.N_utils import AsType
43
44
45 class MACRO_ETAPE(V_ETAPE.ETAPE):
46
47     """
48     """
49
50     def isValid(self, sd='oui', cr='non'):
51         """
52            Methode pour verifier la validite de l'objet ETAPE. Cette methode
53            peut etre appelee selon plusieurs modes en fonction de la valeur
54            de sd et de cr.
55
56            Si cr vaut oui elle cree en plus un compte-rendu.
57
58            Cette methode a plusieurs fonctions :
59
60             - mettre a jour l'etat de self (update)
61
62             - retourner un indicateur de validite 0=non, 1=oui
63
64             - produire un compte-rendu : self.cr
65
66         """
67         if CONTEXT.debug:
68             print(("ETAPE.isValid ", self.nom))
69         if self.state == 'unchanged':
70             return self.valid
71         else:
72             valid = 1
73             # On marque les concepts CO pour verification ulterieure de leur
74             # bonne utilisation
75             l = self.getAllCo()
76             # On verifie que les concepts CO sont bien passes par typeSDProd
77             for c in l:
78                 # if c.etape is self.parent:
79                 if c.isTypCO() != 2:
80                     # le concept est propriete de l'etape parent
81                     # Il n'a pas ete transforme par typeSDProd
82                     # Cette situation est interdite
83                     # Pb: La macro-commande a passe le concept a une commande
84                     # (macro ?) mal definie
85                     if cr == 'oui':
86                         self.cr.fatal("Macro-commande mal definie : le concept n'a pas ete type par un appel a typeSDProd pour %s"  % c.nom)
87                     valid = 0
88
89             valid = valid * self.validChild()
90             valid = valid * self.validRegles(cr)
91
92             if self.reste_val != {}:
93                 if cr == 'oui':
94                     self.cr.fatal(
95                         "unknown keyword : %s"  %','.join(list(self.reste_val.keys())))
96                 valid = 0
97
98             if sd == "non":
99                 # Dans ce cas, on ne calcule qu'une validite partielle, on ne modifie pas l'etat de self
100                 # on retourne simplement l'indicateur valid
101                 return valid
102
103             if self.sd != None:
104                 valid = valid * self.validSdnom(cr)
105
106             if self.definition.reentrant == 'n' and self.reuse:
107                 # Il ne peut y avoir de concept reutilise avec une MACRO  non
108                 # reentrante
109                 if cr == 'oui': self.cr.fatal(
110                         'Macro-commande non reentrante : ne pas utiliser reuse')
111                 valid = 0
112
113             if valid:
114                 valid = self.updateSdprod(cr)
115
116             # Si la macro comprend des etapes internes, on teste leur validite
117             for e in self.etapes:
118                 if not e.isValid():
119                     valid = 0
120                     break
121
122             self.setValid(valid)
123
124             return self.valid
125
126     def updateSdprod(self, cr='non'):
127         """
128              Cette methode met a jour le concept produit en fonction des conditions initiales :
129
130               1. Il n'y a pas de concept retourne (self.definition.sd_prod == None)
131
132               2. Le concept retourne n existait pas (self.sd == None)
133
134               3. Le concept retourne existait. On change alors son type ou on le supprime
135
136              En cas d'erreur (exception) on retourne un indicateur de validite de 0 sinon de 1
137         """
138         sd_prod = self.definition.sd_prod
139         # On memorise le type retourne dans l attribut typret
140         self.typret = None
141         if type(sd_prod) == types.FunctionType:
142             # Type de concept retourne calcule
143             d = self.creeDictValeurs(self.mcListe)
144             try:
145                 # la sd_prod d'une macro a l'objet lui meme en premier argument
146                 # contrairement a une ETAPE ou PROC_ETAPE
147                 # Comme sd_prod peut invoquer la methode typeSDProd qui ajoute
148                 # les concepts produits dans self.sdprods, il faut le mettre a
149                 # zero
150                 self.sdprods = []
151                 sd_prod = sd_prod(*(self,), **d)
152             except:
153                 # Erreur pendant le calcul du type retourne
154                 if CONTEXT.debug:
155                     traceback.print_exc()
156                 self.sd = None
157                 if cr == 'oui':
158                     l = traceback.format_exception(sys.exc_info()[0],
159                                                    sys.exc_info()[1],
160                                                    sys.exc_info()[2])
161                     self.cr.fatal( 'Impossible d affecter un type au resultat\n%s' % ' '.join(l[2:]))
162                 return 0
163         # on teste maintenant si la SD est reutilisee ou s'il faut la
164         # creer
165         valid = 1
166         if self.reuse:
167             # Un concept reutilise a ete specifie
168             if AsType(self.reuse) != sd_prod:
169                 if cr == 'oui':
170                     self.cr.fatal(
171                         'Type de concept reutilise incompatible avec type produit')
172                 valid = 0
173             if self.sdnom != '':
174                 if self.sdnom[0] != '_' and self.reuse.nom != self.sdnom:
175                     # Le nom de la variable de retour (self.sdnom) doit etre le
176                     # meme que celui du concept reutilise (self.reuse.nom)
177                     if cr == 'oui':
178                         self.cr.fatal('Concept reutilise : le nom de la variable de retour devrait etre %s et non %s' % (self.reuse.nom, self.sdnom))
179                     valid = 0
180             if valid:
181                 self.sd = self.reuse
182         else:
183             # Cas d'un concept non reutilise
184             if sd_prod == None:  # Pas de concept retourne
185                 # Que faut il faire de l eventuel ancien sd ?
186                 self.sd = None
187             else:
188                 if self.sd:
189                     # Un sd existe deja, on change son type
190                     if CONTEXT.debug:
191                         print(("changement de type:", self.sd, sd_prod))
192                     if self.sd.__class__ != sd_prod:
193                         self.sd.changeType(sd_prod)
194                     self.typret = sd_prod
195                 else:
196                     # Le sd n existait pas , on ne le cree pas
197                     self.typret = sd_prod
198                     if cr == 'oui':
199                         self.cr.fatal("Concept retourne non defini")
200                     valid = 0
201             if self.definition.reentrant == 'o':
202                 if cr == 'oui':
203                     self.cr.fatal(
204                         'Commande obligatoirement reentrante : specifier reuse=concept')
205                 valid = 0
206         return valid
207
208     def report(self):
209         """
210             Methode pour la generation d un rapport de validation
211         """
212         V_ETAPE.ETAPE.report(self)
213         for e in self.etapes:
214             self.cr.add(e.report())
215         return self.cr