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
43 from Extensions.i18n import tr
49 class ETAPE(V_MCCOMPO.MCCOMPO):
53 def valid_child(self):
54 """ Cette methode teste la validite des mots cles de l'etape """
55 for child in self.mc_liste :
56 if not child.isvalid():
60 def valid_regles(self,cr):
61 """ Cette methode teste la validite des regles de l'etape """
62 text_erreurs,test_regles = self.verif_regles()
65 self.cr.fatal(_(u"Règle(s) non respectée(s) : %s"), text_erreurs)
69 def valid_sdnom(self,cr):
70 """ Cette methode teste la validite du nom du concept produit par l'etape """
72 if self.sd.nom != None :
73 #if self.jdc and self.jdc.definition.code == 'ASTER' and len(self.sd.nom) > 8 :
74 # le nom de la sd doit avoir une longueur <= 8 caractères pour ASTER
76 # self.cr.fatal(_(u"Le nom de concept %s est trop long (8 caractères maxi)"),
79 if self.sd.nom.find('sansnom') != -1 :
80 # la SD est 'sansnom' : --> erreur
82 self.cr.fatal(_(u"Pas de nom pour le concept retourné"))
84 elif re.search('^SD_[0-9]*$', self.sd.nom):
85 # la SD est 'SD_' cad son nom = son id donc pas de nom donné par utilisateur : --> erreur
87 self.cr.fatal(_(u"Nom de concept invalide ('SD_' est réservé)"))
92 if hasattr(self,'valid'):
98 def set_valid(self,valid):
99 old_valid=self.get_valid()
101 self.state = 'unchanged'
102 if not old_valid or old_valid != self.valid :
105 def isvalid(self,sd='oui',cr='non'):
107 Methode pour verifier la validité de l'objet ETAPE. Cette méthode
108 peut etre appelée selon plusieurs modes en fonction de la valeur
111 Si cr vaut oui elle crée en plus un compte-rendu.
113 Cette méthode a plusieurs fonctions :
115 - mettre à jour l'état de self (update)
117 - retourner un indicateur de validité 0=non, 1=oui
119 - produire un compte-rendu : self.cr
122 if CONTEXT.debug : print "ETAPE.isvalid ",self.nom
123 if self.state == 'unchanged' :
126 valid=self.valid_child()
127 valid=valid * self.valid_regles(cr)
129 if self.reste_val != {}:
131 self.cr.fatal(_(u"Mots clés inconnus : %s"), ','.join(self.reste_val.keys()))
135 # Dans ce cas, on ne teste qu'une validité partielle (sans tests sur le concept produit)
136 # Conséquence : on ne change pas l'état ni l'attribut valid, on retourne simplement
137 # l'indicateur de validité valid
140 if self.definition.reentrant == 'n' and self.reuse:
141 # Il ne peut y avoir de concept reutilise avec un OPER non reentrant
143 self.cr.fatal(_(u'Opérateur non réentrant : ne pas utiliser reuse'))
147 # Le concept produit n'existe pas => erreur
149 self.cr.fatal(_(u"Concept retourné non défini"))
152 valid = valid * self.valid_sdnom(cr)
155 valid = self.update_sdprod(cr)
157 self.set_valid(valid)
161 def update_sdprod(self,cr='non'):
163 Cette méthode met à jour le concept produit en fonction des conditions initiales :
165 1. Il n'y a pas de concept retourné (self.definition.sd_prod == None)
167 2. Le concept retourné n existait pas (self.sd == None)
169 3. Le concept retourné existait. On change alors son type ou on le supprime
171 En cas d'erreur (exception) on retourne un indicateur de validité de 0 sinon de 1
173 sd_prod=self.definition.sd_prod
174 if type(sd_prod) == types.FunctionType: # Type de concept retourné calculé
175 d=self.cree_dict_valeurs(self.mc_liste)
177 sd_prod= apply(sd_prod,(),d)
179 # Erreur pendant le calcul du type retourné
180 if CONTEXT.debug:traceback.print_exc()
183 l=traceback.format_exception(sys.exc_info()[0],
186 self.cr.fatal(_(u'Impossible d affecter un type au résultat\n %s'), ' '.join(l[2:]))
188 # on teste maintenant si la SD est r\351utilis\351e ou s'il faut la cr\351er
191 if AsType(self.reuse) != sd_prod:
193 self.cr.fatal(_(u'Type de concept réutilisé incompatible avec type produit'))
196 if self.sdnom[0] != '_' and self.reuse.nom != self.sdnom:
197 # Le nom de la variable de retour (self.sdnom) doit etre le meme que celui du concept reutilise (self.reuse.nom)
199 self.cr.fatal(_(u'Concept réutilisé : le nom de la variable de '
200 u'retour devrait être %s et non %s'),
201 self.reuse.nom, self.sdnom)
203 if valid:self.sd=self.reuse
205 if sd_prod == None:# Pas de concept retourné
206 # Que faut il faire de l eventuel ancien sd ?
210 # Un sd existe deja, on change son type
211 if CONTEXT.debug:print "changement de type:",self.sd,sd_prod
212 if self.sd.__class__ != sd_prod:
213 self.sd.change_type(sd_prod)
215 # Le sd n existait pas , on ne le crée pas
217 self.cr.fatal(_(u"Concept retourné non défini"))
219 if self.definition.reentrant == 'o':
221 self.cr.fatal(_(u'Commande obligatoirement réentrante : spécifier reuse=concept'))
228 Methode pour generation d un rapport de validite
230 self.cr=self.CR(debut=tr('Etape : ')+tr(self.nom) +' ' \
231 + tr(' ligne : ')+`self.appel[0]`\
232 + tr(' fichier :')+`self.appel[1]`,
233 fin = tr('Fin Etape : ')+tr(self.nom))
234 self.state = 'modified'
236 self.isvalid(cr='oui')
237 except AsException,e:
238 if CONTEXT.debug : traceback.print_exc()
239 self.cr.fatal(tr('Etape : ')+tr(self.nom) \
240 + tr(' ligne : ')+`self.appel[0]`\
241 + tr(' fichier :')+`self.appel[1]`, +e)
242 for child in self.mc_liste:
243 self.cr.add(child.report())