]> SALOME platform Git repositories - tools/eficas.git/blob - Validation/V_MACRO_ETAPE.py
Salome HOME
sauve0206
[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) 1991 - 2015  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 """
24    Ce module contient la classe mixin MACRO_ETAPE qui porte les méthodes
25    nécessaires pour réaliser la validation d'un objet de type MACRO_ETAPE
26    dérivé de OBJECT.
27
28    Une classe mixin porte principalement des traitements et est
29    utilisée par héritage multiple pour composer les traitements.
30 """
31 # Modules Python
32 import types
33 import sys
34 import traceback
35
36 # Modules EFICAS
37 import V_MCCOMPO
38 import V_ETAPE
39 from Noyau.N_Exception import AsException
40 from Noyau.N_utils import AsType
41 from Noyau.strfunc import ufmt
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 validité de l'objet ETAPE. Cette méthode
52            peut etre appelée selon plusieurs modes en fonction de la valeur
53            de sd et de cr.
54
55            Si cr vaut oui elle crée en plus un compte-rendu.
56
57            Cette méthode a plusieurs fonctions :
58
59             - mettre à jour l'état de self (update)
60
61             - retourner un indicateur de validité 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.get_all_co()
75             # On verifie que les concepts CO sont bien passes par type_sdprod
76             for c in l:
77                 # if c.etape is self.parent:
78                 if c.is_typco() != 2:
79                     # le concept est propriete de l'etape parent
80                     # Il n'a pas ete transforme par type_sdprod
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(_(u"Macro-commande mal définie : le concept n'a pas été typé par "
86                                         u"un appel à type_sdprod pour %s"), c.nom)
87                     valid = 0
88
89             valid = valid * self.valid_child()
90             valid = valid * self.valid_regles(cr)
91
92             if self.reste_val != {}:
93                 if cr == 'oui':
94                     self.cr.fatal(
95                         #_(u"Mots clés inconnus : %s"), ','.join(self.reste_val.keys()))
96                         _(u"unknown keyword : %s"), ','.join(self.reste_val.keys()))
97                 valid = 0
98
99             if sd == "non":
100                 # Dans ce cas, on ne calcule qu'une validite partielle, on ne modifie pas l'état de self
101                 # on retourne simplement l'indicateur valid
102                 return valid
103
104             if self.sd != None:
105                 valid = valid * self.valid_sdnom(cr)
106
107             if self.definition.reentrant == 'n' and self.reuse:
108                 # Il ne peut y avoir de concept reutilise avec une MACRO  non
109                 # reentrante
110                 if cr == 'oui':
111                     self.cr.fatal(
112                         _(u'Macro-commande non réentrante : ne pas utiliser reuse'))
113                 valid = 0
114
115             if valid:
116                 valid = self.update_sdprod(cr)
117
118             # Si la macro comprend des etapes internes, on teste leur validite
119             for e in self.etapes:
120                 if not e.isvalid():
121                     valid = 0
122                     break
123
124             self.set_valid(valid)
125
126             return self.valid
127
128     def update_sdprod(self, cr='non'):
129         """
130              Cette méthode met à jour le concept produit en fonction des conditions initiales :
131
132               1. Il n'y a pas de concept retourné (self.definition.sd_prod == None)
133
134               2. Le concept retourné n existait pas (self.sd == None)
135
136               3. Le concept retourné existait. On change alors son type ou on le supprime
137
138              En cas d'erreur (exception) on retourne un indicateur de validité de 0 sinon de 1
139         """
140         sd_prod = self.definition.sd_prod
141         # On memorise le type retourné dans l attribut typret
142         self.typret = None
143         if type(sd_prod) == types.FunctionType:
144             # Type de concept retourné calculé
145             d = self.cree_dict_valeurs(self.mc_liste)
146             try:
147                 # la sd_prod d'une macro a l'objet lui meme en premier argument
148                 # contrairement à une ETAPE ou PROC_ETAPE
149                 # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute
150                 # les concepts produits dans self.sdprods, il faut le mettre à
151                 # zéro
152                 self.sdprods = []
153                 sd_prod = apply(sd_prod, (self,), d)
154             except:
155                 # Erreur pendant le calcul du type retourné
156                 if CONTEXT.debug:
157                     traceback.print_exc()
158                 self.sd = None
159                 if cr == 'oui':
160                     l = traceback.format_exception(sys.exc_info()[0],
161                                                    sys.exc_info()[1],
162                                                    sys.exc_info()[2])
163                     self.cr.fatal(
164                         _(u'Impossible d affecter un type au résultat\n%s'), ' '.join(l[2:]))
165                 return 0
166         # on teste maintenant si la SD est r\351utilis\351e ou s'il faut la
167         # cr\351er
168         valid = 1
169         if self.reuse:
170             # Un concept reutilise a ete specifie
171             if AsType(self.reuse) != sd_prod:
172                 if cr == 'oui':
173                     self.cr.fatal(
174                         _(u'Type de concept réutilisé incompatible avec type produit'))
175                 valid = 0
176             if self.sdnom != '':
177                 if self.sdnom[0] != '_' and self.reuse.nom != self.sdnom:
178                     # Le nom de la variable de retour (self.sdnom) doit etre le
179                     # meme que celui du concept reutilise (self.reuse.nom)
180                     if cr == 'oui':
181                         self.cr.fatal(_(u'Concept réutilisé : le nom de la variable de '
182                                         u'retour devrait être %s et non %s'),
183                                       self.reuse.nom, self.sdnom)
184                     valid = 0
185             if valid:
186                 self.sd = self.reuse
187         else:
188             # Cas d'un concept non reutilise
189             if sd_prod == None:  # Pas de concept retourné
190                 # Que faut il faire de l eventuel ancien sd ?
191                 self.sd = None
192             else:
193                 if self.sd:
194                     # Un sd existe deja, on change son type
195                     if CONTEXT.debug:
196                         print "changement de type:", self.sd, sd_prod
197                     if self.sd.__class__ != sd_prod:
198                         self.sd.change_type(sd_prod)
199                     self.typret = sd_prod
200                 else:
201                     # Le sd n existait pas , on ne le crée pas
202                     self.typret = sd_prod
203                     if cr == 'oui':
204                         self.cr.fatal(_(u"Concept retourné non défini"))
205                     valid = 0
206             if self.definition.reentrant == 'o':
207                 if cr == 'oui':
208                     self.cr.fatal(
209                         _(u'Commande obligatoirement réentrante : spécifier reuse=concept'))
210                 valid = 0
211         return valid
212
213     def report(self):
214         """
215             Methode pour la generation d un rapport de validation
216         """
217         V_ETAPE.ETAPE.report(self)
218         for e in self.etapes:
219             self.cr.add(e.report())
220         return self.cr