1 # -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2013 EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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
27 Une classe mixin porte principalement des traitements et est
28 utilisée par héritage multiple pour composer les traitements.
38 from Noyau.N_Exception import AsException
39 from Noyau.N_utils import AsType
40 from Noyau.strfunc import ufmt
42 class ETAPE(V_MCCOMPO.MCCOMPO):
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():
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()
58 self.cr.fatal(_(u"Règle(s) non respectée(s) : %s"), text_erreurs)
62 def valid_sdnom(self,cr):
63 """ Cette methode teste la validite du nom du concept produit par l'etape """
65 if self.sd.nom != None :
66 #if self.jdc and self.jdc.definition.code == 'ASTER' and len(self.sd.nom) > 8 :
67 # le nom de la sd doit avoir une longueur <= 8 caractères pour ASTER
69 # self.cr.fatal(_(u"Le nom de concept %s est trop long (8 caractères maxi)"),
72 if self.sd.nom.find('sansnom') != -1 :
73 # la SD est 'sansnom' : --> erreur
75 self.cr.fatal(_(u"Pas de nom pour le concept retourné"))
77 elif re.search('^SD_[0-9]*$', self.sd.nom):
78 # la SD est 'SD_' cad son nom = son id donc pas de nom donné par utilisateur : --> erreur
80 self.cr.fatal(_(u"Nom de concept invalide ('SD_' est réservé)"))
85 if hasattr(self,'valid'):
91 def set_valid(self,valid):
92 old_valid=self.get_valid()
94 self.state = 'unchanged'
95 if not old_valid or old_valid != self.valid :
98 def isvalid(self,sd='oui',cr='non'):
100 Methode pour verifier la validité de l'objet ETAPE. Cette méthode
101 peut etre appelée selon plusieurs modes en fonction de la valeur
104 Si cr vaut oui elle crée en plus un compte-rendu.
106 Cette méthode a plusieurs fonctions :
108 - mettre à jour l'état de self (update)
110 - retourner un indicateur de validité 0=non, 1=oui
112 - produire un compte-rendu : self.cr
115 if CONTEXT.debug : print "ETAPE.isvalid ",self.nom
116 if self.state == 'unchanged' :
119 valid=self.valid_child()
120 valid=valid * self.valid_regles(cr)
122 if self.reste_val != {}:
124 self.cr.fatal(_(u"Mots clés inconnus : %s"), ','.join(self.reste_val.keys()))
128 # Dans ce cas, on ne teste qu'une validité partielle (sans tests sur le concept produit)
129 # Conséquence : on ne change pas l'état ni l'attribut valid, on retourne simplement
130 # l'indicateur de validité valid
133 if self.definition.reentrant == 'n' and self.reuse:
134 # Il ne peut y avoir de concept reutilise avec un OPER non reentrant
136 self.cr.fatal(_(u'Opérateur non réentrant : ne pas utiliser reuse'))
140 # Le concept produit n'existe pas => erreur
142 self.cr.fatal(_(u"Concept retourné non défini"))
145 valid = valid * self.valid_sdnom(cr)
148 valid = self.update_sdprod(cr)
150 self.set_valid(valid)
154 def update_sdprod(self,cr='non'):
156 Cette méthode met à jour le concept produit en fonction des conditions initiales :
158 1. Il n'y a pas de concept retourné (self.definition.sd_prod == None)
160 2. Le concept retourné n existait pas (self.sd == None)
162 3. Le concept retourné existait. On change alors son type ou on le supprime
164 En cas d'erreur (exception) on retourne un indicateur de validité de 0 sinon de 1
166 sd_prod=self.definition.sd_prod
167 if type(sd_prod) == types.FunctionType: # Type de concept retourné calculé
168 d=self.cree_dict_valeurs(self.mc_liste)
170 sd_prod= apply(sd_prod,(),d)
172 # Erreur pendant le calcul du type retourné
173 if CONTEXT.debug:traceback.print_exc()
176 l=traceback.format_exception(sys.exc_info()[0],
179 self.cr.fatal(_(u'Impossible d affecter un type au résultat\n %s'), ' '.join(l[2:]))
181 # on teste maintenant si la SD est r\351utilis\351e ou s'il faut la cr\351er
184 if AsType(self.reuse) != sd_prod:
186 self.cr.fatal(_(u'Type de concept réutilisé incompatible avec type produit'))
189 if self.sdnom[0] != '_' and self.reuse.nom != self.sdnom:
190 # Le nom de la variable de retour (self.sdnom) doit etre le meme que celui du concept reutilise (self.reuse.nom)
192 self.cr.fatal(_(u'Concept réutilisé : le nom de la variable de '
193 u'retour devrait être %s et non %s'),
194 self.reuse.nom, self.sdnom)
196 if valid:self.sd=self.reuse
198 if sd_prod == None:# Pas de concept retourné
199 # Que faut il faire de l eventuel ancien sd ?
203 # Un sd existe deja, on change son type
204 if CONTEXT.debug:print "changement de type:",self.sd,sd_prod
205 if self.sd.__class__ != sd_prod:
206 self.sd.change_type(sd_prod)
208 # Le sd n existait pas , on ne le crée pas
210 self.cr.fatal(_(u"Concept retourné non défini"))
212 if self.definition.reentrant == 'o':
214 self.cr.fatal(_(u'Commande obligatoirement réentrante : spécifier reuse=concept'))
221 Methode pour generation d un rapport de validite
223 self.cr=self.CR(debut=u'Etape : '+self.nom \
224 + u' ligne : '+`self.appel[0]`\
225 + u' fichier : '+`self.appel[1]`,
226 fin = u'Fin Etape : '+self.nom)
227 self.state = 'modified'
229 self.isvalid(cr='oui')
230 except AsException,e:
231 if CONTEXT.debug : traceback.print_exc()
232 self.cr.fatal(_(u'Etape : %s ligne : %r fichier : %r %s'),
233 self.nom, self.appel[0], self.appel[1], e)
234 for child in self.mc_liste:
235 self.cr.add(child.report())