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