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