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