Salome HOME
PN : correction de bug ???
[tools/eficas.git] / Validation / V_ETAPE.py
1 # -*- coding: utf-8 -*-
2 #@ MODIF V_ETAPE Validation  DATE 26/09/2003   AUTEUR DURAND C.DURAND 
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    Ce module contient la classe mixin ETAPE qui porte les méthodes
24    nécessaires pour réaliser la validation d'un objet de type ETAPE
25    dérivé de OBJECT.
26
27    Une classe mixin porte principalement des traitements et est
28    utilisée par héritage multiple pour composer les traitements.
29 """
30 # Modules Python
31 import string,types,sys
32 import traceback
33
34 # Modules EFICAS
35 import V_MCCOMPO
36 from Noyau.N_Exception import AsException
37 from Noyau.N_utils import AsType
38
39 class ETAPE(V_MCCOMPO.MCCOMPO):
40    """
41    """
42
43    def valid_child(self):
44        """ Cette methode teste la validite des mots cles de l'etape """
45        for child in self.mc_liste :
46            if not child.isvalid():
47               return 0 
48        return 1
49
50    def valid_regles(self,cr):
51        """ Cette methode teste la validite des regles de l'etape """
52        text_erreurs,test_regles = self.verif_regles()
53        if not test_regles :
54           if cr == 'oui' : self.cr.fatal(string.join(("Règle(s) non respectée(s) :", text_erreurs)))
55           return 0 
56        return 1
57
58    def valid_sdnom(self,cr):
59        """ Cette methode teste la validite du nom du concept produit par l'etape """
60        valid=1
61        if self.sd.nom != None :
62           if self.jdc and self.jdc.definition.code == 'ASTER' and len(self.sd.nom) > 8 :
63              #  le nom de la sd doit avoir une longueur <= 8 caractères pour ASTER
64              if cr == 'oui' :
65                 self.cr.fatal("Le nom de concept %s est trop long (8 caractères maxi)" %self.sd.nom)
66              valid = 0
67           if string.find(self.sd.nom,'sansnom') != -1 :
68              # la SD est 'sansnom' : --> erreur
69              if cr == 'oui' :
70                 self.cr.fatal("Pas de nom pour le concept retourné")
71              valid = 0
72           elif string.find(self.sd.nom,'SD_') != -1 :
73              # la SD est 'SD_' cad son nom = son id donc pas de nom donné par utilisateur : --> erreur
74              if cr == 'oui' :
75                 self.cr.fatal("Pas de nom pour le concept retourné")
76              valid = 0
77        return valid
78
79    def get_valid(self):
80        if hasattr(self,'valid'):
81           return self.valid
82        else:
83           self.valid=None
84           return None
85
86    def set_valid(self,valid):
87        old_valid=self.get_valid()
88        self.valid = valid
89        self.state = 'unchanged'
90        if not old_valid or old_valid != self.valid : 
91            self.init_modif_up()
92
93    def isvalid(self,sd='oui',cr='non'):
94       """ 
95          Methode pour verifier la validité de l'objet ETAPE. Cette méthode
96          peut etre appelée selon plusieurs modes en fonction de la valeur
97          de sd et de cr.
98
99          Si cr vaut oui elle crée en plus un compte-rendu.
100
101          Cette méthode a plusieurs fonctions :
102
103           - mettre à jour l'état de self (update)
104
105           - retourner un indicateur de validité 0=non, 1=oui
106
107           - produire un compte-rendu : self.cr
108
109       """
110       if CONTEXT.debug : print "ETAPE.isvalid ",self.nom
111       if self.state == 'unchanged' :
112         return self.valid
113       else:
114         valid=self.valid_child()
115         valid=valid * self.valid_regles(cr)
116
117         if self.reste_val != {}:
118           if cr == 'oui' :
119             self.cr.fatal("Mots cles inconnus :" + string.join(self.reste_val.keys(),','))
120           valid=0
121
122         if sd == "non":
123           # Dans ce cas, on ne teste qu'une validité partielle (sans tests sur le concept produit)
124           # Conséquence : on ne change pas l'état ni l'attribut valid, on retourne simplement
125           # l'indicateur de validité valid
126           return valid
127
128         if self.definition.reentrant == 'n' and self.reuse:
129           # Il ne peut y avoir de concept reutilise avec un OPER non reentrant
130           if cr == 'oui' : self.cr.fatal('Operateur non reentrant : ne pas utiliser reuse ')
131           valid=0
132
133         if self.sd == None:
134           # Le concept produit n'existe pas => erreur
135           if cr == 'oui' : self.cr.fatal("Concept retourné non défini")
136           valid = 0
137         else:
138           valid = valid * self.valid_sdnom(cr)
139
140         if valid:
141           valid = self.update_sdprod(cr)
142
143         self.set_valid(valid)
144
145         return self.valid
146
147    def update_sdprod(self,cr='non'):
148       """ 
149            Cette méthode met à jour le concept produit en fonction des conditions initiales :
150
151             1- Il n'y a pas de concept retourné (self.definition.sd_prod == None)
152
153             2- Le concept retourné n existait pas (self.sd == None)
154
155             3- Le concept retourné existait. On change alors son type ou on le supprime
156
157            En cas d'erreur (exception) on retourne un indicateur de validité de 0 sinon de 1
158       """
159       sd_prod=self.definition.sd_prod
160       if type(sd_prod) == types.FunctionType: # Type de concept retourné calculé
161         d=self.cree_dict_valeurs(self.mc_liste)
162         try:
163           sd_prod= apply(sd_prod,(),d)
164         except:
165           # Erreur pendant le calcul du type retourné
166           if CONTEXT.debug:traceback.print_exc()
167           self.sd=None
168           if cr == 'oui' : 
169              l=traceback.format_exception(sys.exc_info()[0],
170                                            sys.exc_info()[1],
171                                            sys.exc_info()[2])
172              self.cr.fatal('Impossible d affecter un type au résultat\n'+string.join(l[2:]))
173           return 0
174       # on teste maintenant si la SD est r\351utilis\351e ou s'il faut la cr\351er
175       valid=1
176       if self.reuse:
177         if AsType(self.reuse) != sd_prod:
178           if cr == 'oui' : self.cr.fatal('Type de concept reutilise incompatible avec type produit')
179           valid= 0
180         if self.sdnom!='':
181            if self.sdnom[0] != '_' and self.reuse.nom != self.sdnom:
182              # Le nom de la variable de retour (self.sdnom) doit etre le meme que celui du concept reutilise (self.reuse.nom)
183              if cr == 'oui' : 
184                 self.cr.fatal('Concept reutilise : le nom de la variable de retour devrait etre %s et non %s' %(self.reuse.nom,self.sdnom))
185              valid= 0
186         if valid:self.sd=self.reuse
187       else:
188         if sd_prod == None:# Pas de concept retourné
189           # Que faut il faire de l eventuel ancien sd ?
190           self.sd = None
191         else:
192           if self.sd: 
193              # Un sd existe deja, on change son type
194              self.sd.__class__=sd_prod
195           else: 
196              # Le sd n existait pas , on ne le crée pas
197              if cr == 'oui' : self.cr.fatal("Concept retourné non défini")
198              valid=0 
199         if self.definition.reentrant == 'o':
200            if cr == 'oui' : self.cr.fatal('Commande obligatoirement reentrante : specifier reuse=concept')
201            valid=0 
202       return valid
203
204
205    def report(self):
206       """ 
207           Methode pour generation d un rapport de validite
208       """
209       self.cr=self.CR(debut='Etape : '+self.nom \
210                 + '    ligne : '+`self.appel[0]`\
211                 + '    fichier : '+`self.appel[1]`,
212                  fin = 'Fin Etape : '+self.nom)
213       self.state = 'modified'
214       try:
215         self.isvalid(cr='oui')
216       except AsException,e:
217         if CONTEXT.debug : traceback.print_exc()
218         self.cr.fatal(string.join(('Etape :',self.nom,
219                               'ligne :',`self.appel[0]`,
220                               'fichier :',`self.appel[1]`,str(e))))
221       for child in self.mc_liste:
222         self.cr.add(child.report())
223       return self.cr
224