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.
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.
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.
19 # ======================================================================
23 Ce module contient la classe mixin ETAPE qui porte les methodes
24 necessaires pour realiser la validation d'un objet de type ETAPE
27 Une classe mixin porte principalement des traitements et est
28 utilisee par heritage multiple pour composer les traitements.
30 from __future__ import print_function
31 from __future__ import absolute_import
40 from . import V_MCCOMPO
41 from Noyau import MAXSIZE, MAXSIZE_MSGCHK
42 from Noyau.N_Exception import AsException
43 from Noyau.N_utils import AsType
44 from Extensions.i18n import tr
48 class ETAPE(V_MCCOMPO.MCCOMPO):
54 """ Cette methode teste la validite des mots cles de l'etape """
55 for child in self.mcListe:
56 if not child.isValid():
60 def validRegles(self, cr):
61 """ Cette methode teste la validite des regles de l'etape """
62 text_erreurs, test_regles = self.verifRegles()
65 self.cr.fatal( "Regle(s) non respectee(s) : %s" % text_erreurs)
69 def validSdnom(self, cr):
70 """ Cette methode teste la validite du nom du concept produit par l'etape """
72 if self.sd.nom != None:
73 if self.sd.nom.find('sansnom') != -1:
74 # la SD est 'sansnom' : --> erreur
76 self.cr.fatal(("object must have a name"))
78 elif re.search('^SD_[0-9]*$', self.sd.nom):
79 # la SD est 'SD_' cad son nom = son id donc pas de nom donne
80 # par utilisateur : --> erreur
82 self.cr.fatal( ("invalid name ('SD_' is a reserved keyword)"))
87 if hasattr(self, 'valid'):
93 def setValid(self, valid):
94 old_valid = self.getValid()
96 self.state = 'unchanged'
97 if not old_valid or old_valid != self.valid:
100 def isValid(self, sd='oui', cr='non'):
102 Methode pour verifier la validite de l'objet ETAPE. Cette methode
103 peut etre appelee selon plusieurs modes en fonction de la valeur
106 Si cr vaut oui elle cree en plus un compte-rendu.
108 Cette methode a plusieurs fonctions :
110 - mettre a jour l'etat de self (update)
112 - retourner un indicateur de validite 0=non, 1=oui
114 - produire un compte-rendu : self.cr
119 # print(("ETAPE.isValid ", self.nom, self.state))
121 # traceback.print_stack()
122 if self.state == 'unchanged':
125 valid = self.validChild()
126 valid = valid * self.validRegles(cr)
128 if not hasattr(self,'cr') :
129 from Noyau.N_CR import CR
133 if self.reste_val != {}:
136 "unknown keywords : %s" % ','.join(list(self.reste_val.keys())))
140 # Dans ce cas, on ne teste qu'une validite partielle (sans tests sur le concept produit)
141 # Consequence : on ne change pas l'etat ni l'attribut valid, on retourne simplement
142 # l'indicateur de validite valid
145 if self.definition.reentrant == 'n' and self.reuse:
146 # Il ne peut y avoir de concept reutilise avec un OPER non
150 'Operateur non reentrant : ne pas utiliser reuse')
154 # Le concept produit n'existe pas => erreur
156 self.cr.fatal(("Concept is not defined"))
159 valid = valid * self.validSdnom(cr)
162 valid = self.updateSdprod(cr)
168 def updateSdprod(self, cr='non'):
170 Cette methode met a jour le concept produit en fonction des conditions initiales :
172 1. Il n'y a pas de concept retourne (self.definition.sd_prod == None)
174 2. Le concept retourne n existait pas (self.sd == None)
176 3. Le concept retourne existait. On change alors son type ou on le supprime
178 En cas d'erreur (exception) on retourne un indicateur de validite de 0 sinon de 1
180 sd_prod = self.definition.sd_prod
181 if type(sd_prod) == types.FunctionType: # Type de concept retourne calcule
182 d = self.creeDictValeurs(self.mcListe)
184 sd_prod = sd_prod(*(), **d)
186 # Erreur pendant le calcul du type retourne
188 traceback.print_exc()
191 l = traceback.format_exception(sys.exc_info()[0],
195 'unable to affect type to concept\n %s' % ' '.join(l[2:]))
197 # on teste maintenant si la SD est reutilisee ou s'il faut la
201 if AsType(self.reuse) != sd_prod:
204 ('Type de concept reutilise incompatible avec type produit'))
207 if self.sdnom[0] != '_' and self.reuse.nom != self.sdnom:
208 # Le nom de la variable de retour (self.sdnom) doit etre le
209 # meme que celui du concept reutilise (self.reuse.nom)
211 self.cr.fatal('Concept reutilise : le nom de la variable de retour devrait etre %s et non %s' % ( self.reuse.nom, self.sdnom))
216 if sd_prod == None: # Pas de concept retourne
217 # Que faut il faire de l eventuel ancien sd ?
221 # Un sd existe deja, on change son type
223 print(("changement de type:", self.sd, sd_prod))
224 if self.sd.__class__ != sd_prod:
225 self.sd.changeType(sd_prod)
227 # Le sd n existait pas , on ne le cree pas
229 self.cr.fatal("Concept retourne non defini")
231 if self.definition.reentrant == 'o':
234 ('Commande obligatoirement reentrante : specifier reuse=concept'))
240 Methode pour generation d un rapport de validite
242 self.cr = self.CR(debut='Command : ' + tr(self.nom)
243 + ' line : ' + repr(self.appel[0])
244 + ' file : ' + repr(self.appel[1]),
245 fin='End Command : ' + tr(self.nom))
246 self.state = 'modified'
248 self.isValid(cr='oui')
249 except AsException as e:
251 traceback.print_exc()
252 self.cr.fatal('Command : %s line : %r file : %r %s' % (tr(self.nom), self.appel[0], self.appel[1], e))
254 for child in self.mcListe:
257 print (MAXSIZE_MSGCHK.format(MAXSIZE, len(self.mcListe)))
259 self.cr.add(child.report())