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