Salome HOME
CCAR: correction d'un probleme de mise a jour de contexte lors d'une insertion
[tools/eficas.git] / Validation / V_MACRO_ETAPE.py
1 #@ MODIF V_MACRO_ETAPE Validation  DATE 22/02/2005   AUTEUR DURAND C.DURAND 
2 # -*- coding: iso-8859-1 -*-
3 #            CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
6 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
7 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
8 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR   
9 # (AT YOUR OPTION) ANY LATER VERSION.                                 
10 #
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT 
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF          
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU    
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.                            
15 #
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE   
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,       
18 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.      
19 #                                                                       
20 #                                                                       
21 # ======================================================================
22
23
24 """
25    Ce module contient la classe mixin MACRO_ETAPE qui porte les méthodes
26    nécessaires pour réaliser la validation d'un objet de type MACRO_ETAPE
27    dérivé de OBJECT.
28
29    Une classe mixin porte principalement des traitements et est
30    utilisée par héritage multiple pour composer les traitements.
31 """
32 # Modules Python
33 import string,types,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
42 class MACRO_ETAPE(V_ETAPE.ETAPE):
43    """
44    """
45
46    def isvalid(self,sd='oui',cr='non'):
47       """ 
48          Methode pour verifier la validité de l'objet ETAPE. Cette méthode
49          peut etre appelée selon plusieurs modes en fonction de la valeur
50          de sd et de cr.
51
52          Si cr vaut oui elle crée en plus un compte-rendu.
53
54          Cette méthode a plusieurs fonctions :
55
56           - mettre à jour l'état de self (update)
57
58           - retourner un indicateur de validité 0=non, 1=oui
59
60           - produire un compte-rendu : self.cr
61
62       """
63       if CONTEXT.debug : print "ETAPE.isvalid ",self.nom
64       if self.state == 'unchanged' :
65         return self.valid
66       else:
67         valid=1
68         # On marque les concepts CO pour verification ulterieure de leur bonne utilisation
69         l=self.mark_CO()
70         # On verifie que les concepts CO sont bien passes par type_sdprod
71         for c in l:
72           if c.etape is self.parent:
73              # le concept est propriete de l'etape parent
74              # Il n'a pas ete transforme par type_sdprod
75              # Cette situation est interdite
76              # Pb: La macro-commande a passe le concept a une commande (macro ?) mal definie
77              if cr =='oui': 
78                self.cr.fatal("Macro-commande mal definie : manque probablement appel a type_sdprod pour %s" % c.nom)
79              valid=0
80
81         valid=valid * self.valid_child()
82         valid=valid * self.valid_regles(cr)
83
84         if self.reste_val != {}:
85           if cr == 'oui' :
86             self.cr.fatal("Mots cles inconnus :" + string.join(self.reste_val.keys(),','))
87           valid=0
88
89         if sd == "non":
90            # Dans ce cas, on ne calcule qu'une validite partielle, on ne modifie pas l'état de self
91            # on retourne simplement l'indicateur valid
92            return valid
93
94         if self.sd != None :
95            valid = valid * self.valid_sdnom(cr)
96
97         if self.definition.reentrant == 'n' and self.reuse:
98            # Il ne peut y avoir de concept reutilise avec une MACRO  non reentrante
99            if cr == 'oui' : self.cr.fatal('Macro-commande non reentrante : ne pas utiliser reuse ')
100            valid=0
101
102         if valid:
103           valid = self.update_sdprod(cr)
104
105         # Si la macro comprend des etapes internes, on teste leur validite
106         for e in self.etapes:
107           if not e.isvalid():
108             valid=0
109             break
110
111         self.set_valid(valid)
112
113         return self.valid
114
115    def update_sdprod(self,cr='non'):
116       """ 
117            Cette méthode met à jour le concept produit en fonction des conditions initiales :
118
119             1- Il n'y a pas de concept retourné (self.definition.sd_prod == None)
120
121             2- Le concept retourné n existait pas (self.sd == None)
122
123             3- Le concept retourné existait. On change alors son type ou on le supprime
124
125            En cas d'erreur (exception) on retourne un indicateur de validité de 0 sinon de 1
126       """
127       sd_prod=self.definition.sd_prod
128       # On memorise le type retourné dans l attribut typret
129       self.typret=None 
130       if type(sd_prod) == types.FunctionType: 
131         # Type de concept retourné calculé
132         d=self.cree_dict_valeurs(self.mc_liste)
133         try:
134           # la sd_prod d'une macro a l'objet lui meme en premier argument
135           # contrairement à une ETAPE ou PROC_ETAPE
136           # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute
137           # les concepts produits dans self.sdprods, il faut le mettre à zéro
138           self.sdprods=[]
139           sd_prod= apply(sd_prod,(self,),d)
140         except:
141           # Erreur pendant le calcul du type retourné
142           if CONTEXT.debug:traceback.print_exc()
143           self.sd=None
144           if cr == 'oui' : 
145              l=traceback.format_exception(sys.exc_info()[0],
146                                            sys.exc_info()[1],
147                                            sys.exc_info()[2])
148              self.cr.fatal('Impossible d affecter un type au résultat\n'+string.join(l[2:]))
149           return 0
150       # on teste maintenant si la SD est r\351utilis\351e ou s'il faut la cr\351er
151       valid=1
152       if self.reuse:
153         # Un concept reutilise a ete specifie
154         if AsType(self.reuse) != sd_prod:
155           if cr == 'oui' : self.cr.fatal('Type de concept reutilise incompatible avec type produit')
156           valid=0
157         if self.sdnom!='':
158            if self.sdnom[0] != '_' and self.reuse.nom != self.sdnom:
159              # Le nom de la variable de retour (self.sdnom) doit etre le meme que celui du concept reutilise (self.reuse.nom)
160              if cr == 'oui' :
161                 self.cr.fatal('Concept reutilise : le nom de la variable de retour devrait etre %s et non %s' %(self.reuse.nom,self.sdnom))
162              valid= 0
163         if valid:self.sd=self.reuse
164       else:
165         if sd_prod == None:# Pas de concept retourné
166           # Que faut il faire de l eventuel ancien sd ?
167           self.sd = None
168         else:
169           if self.sd: 
170             # Un sd existe deja, on change son type
171             self.sd.__class__=sd_prod
172             self.typret=sd_prod
173           else: 
174             # Le sd n existait pas , on ne le crée pas
175             self.typret=sd_prod
176             if cr == 'oui' : self.cr.fatal("Concept retourné non défini")
177             valid=0 
178         if self.definition.reentrant == 'o':
179            if cr == 'oui' : self.cr.fatal('Commande obligatoirement reentrante : specifier reuse=concept')
180            valid=0
181       return valid
182
183    def report(self):
184       """ 
185           Methode pour la generation d un rapport de validation
186       """
187       V_ETAPE.ETAPE.report(self)
188       for e in self.etapes :
189         self.cr.add(e.report())
190       return self.cr
191