1 #@ MODIF V_MCSIMP Validation DATE 27/03/2002 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.
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.
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.
20 # ======================================================================
22 Ce module contient la classe mixin MCSIMP qui porte les méthodes
23 nécessaires pour réaliser la validation d'un objet de type MCSIMP
26 Une classe mixin porte principalement des traitements et est
27 utilisée par héritage multiple pour composer les traitements.
34 from Noyau import N_CR
35 from Noyau.N_Exception import AsException
40 Cette classe est quasiment identique à la classe originale d'EFICAS
41 a part quelques changements cosmétiques et des chagements pour la
42 faire fonctionner de facon plus autonome par rapport à l'environnement
45 A mon avis, il faudrait aller plus loin et réduire les dépendances
46 amont au strict nécessaire.
48 - Est il indispensable de faire l'évaluation de la valeur dans le contexte
49 du jdc dans cette classe.
51 - Ne pourrait on pas doter les objets en présence des méthodes suffisantes
52 pour éviter les tests un peu particuliers sur GEOM, PARAMETRE et autres. J'ai
53 d'ailleurs modifié la classe pour éviter l'import de GEOM
59 self.state='undetermined'
61 def isvalid(self,cr='non'):
63 Cette méthode retourne un indicateur de validité de l'objet
66 - 0 si l'objet est invalide
68 - 1 si l'objet est valide
70 Le pramètre cr permet de paramétrer le traitement. Si cr == 'oui'
71 la méthode construit également un comte-rendu de validation
72 dans self.cr qui doit avoir été créé préalablement.
74 if self.state == 'unchanged':
78 if hasattr(self,'valid'):
79 old_valid = self.valid
84 if self.isoblig() and v == None :
86 self.cr.fatal(string.join(("Mot-clé : ",self.nom," obligatoire non valorisé")))
89 valid = self.verif_type(cr=cr)*self.verif_into(cr=cr)*self.verif_card(cr=cr)
91 self.state = 'unchanged'
92 # Si la validité du mot clé a changé, on le signale à l'objet parent
94 if old_valid != self.valid : self.init_modif_up()
98 """ indique si le mot-clé est obligatoire
100 return self.definition.statut=='o'
102 def verif_card(self,cr='non'):
104 un mot-clé simple ne peut etre répété :
105 la cardinalité ici s'entend par la vérification que le nombre d'arguments de self.valeur
106 est bien compris entre self.min et self.max dans le cas où il s'agit d'une liste
109 min=self.definition.min
110 max=self.definition.max
111 if type(self.valeur) in (types.ListType,types.TupleType) and 'C' not in self.definition.type :
112 if len(self.valeur) < min or len(self.valeur)>max:
114 self.cr.fatal("Nombre d'arguments %s incorrects pour %s (min = %s, max = %s)" %(`self.valeur`,self.nom,min,max))
117 if self.valeur == None :
119 # on n'a pas d'objet et on en attend au moins un
123 # on n'a qu'un objet et on en attend plus d'1
127 def verif_type(self,val=None,cr='non'):
130 Cette méthode a plusieurs modes de fonctionnement liés à la valeur de val et de cr.
131 Si cr ne vaut pas 'oui' : elle ne remplit pas le compte-rendu self.cr
132 Si val vaut None, elle vérifie le type de self.valeur
133 Si val ne vaut pas None, elle vérifie le type de val
134 PARAMETRE DE RETOUR :
135 Cette méthode retourne une valeur booléenne qui vaut 1 si le type est correct ou 0 sinon
144 self.cr.fatal("None n'est pas une valeur autorisée")
146 if type(valeur) == types.TupleType:
147 # on peut avoir à faire à un complexe ou une liste de valeurs ...
148 if self.is_complexe(valeur) : return 1
151 if not self.verif_type(val=val,cr=cr) : return 0
153 elif type(valeur) == types.ListType:
155 if not self.verif_type(val=val,cr=cr) : return 0
158 # on n'a pas de tuple ...il faut tester sur tous les types ou les valeurs possibles
159 # XXX Pourquoi into est il traité ici et pas seulement dans verif_into ???
160 if self.definition.into != None :
162 if valeur in self.definition.into :
166 self.cr.fatal("%s n'est pas une valeur autorisée" %valeur)
169 print "problème avec :",self.nom
170 print 'valeur =',valeur
172 for type_permis in self.definition.type:
173 if self.compare_type(valeur,type_permis) : return 1
174 # si on sort de la boucle précédente par ici c'est que l'on n'a trouvé aucun type valable --> valeur refusée
176 self.cr.fatal("%s n'est pas d'un type autorisé" %`valeur`)
179 def verif_into(self,cr='non'):
181 Vérifie si la valeur de self est bien dans l'ensemble discret de valeurs
182 donné dans le catalogue derrière l'attribut into ou vérifie que valeur est bien compris
183 entre val_min et val_max
185 if self.definition.into == None :
186 #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
187 if type(self.valeur)==types.TupleType :
189 for val in self.valeur :
190 if type(val)!=types.StringType and type(val)!=types.InstanceType:
191 test = test*self.isinintervalle(val,cr=cr)
195 if type(val)!=types.StringType and type(val)!=types.InstanceType:
196 return self.isinintervalle(self.valeur,cr=cr)
200 # on est dans le cas d'un ensemble discret de valeurs possibles (into)
201 if type(self.valeur) == types.TupleType :
202 for e in self.valeur:
203 if e not in self.definition.into:
205 self.cr.fatal(string.join(("La valeur :",`e`," n'est pas permise pour le mot-clé :",self.nom)))
208 if self.valeur == None or self.valeur not in self.definition.into:
210 self.cr.fatal(string.join(("La valeur :",`self.valeur`," n'est pas permise pour le mot-clé :",self.nom)))
214 def is_complexe(self,valeur):
215 """ Retourne 1 si valeur est un complexe, 0 sinon """
216 if type(valeur) == types.StringType :
217 # on teste une valeur issue d'une entry (valeur saisie depuis EFICAS)
218 #XXX Il serait peut etre plus judicieux d'appeler une méthode de self.jdc
219 #XXX qui retournerait l'objet résultat de l'évaluation
220 #XXX ou meme de faire cette evaluation a l'exterieur de cette classe ??
221 if not self.jdc :return 0
223 valeur = eval(valeur,self.jdc.g_context)
226 if type(valeur) == types.InstanceType :
227 #XXX je n'y touche pas pour ne pas tout casser mais il serait
228 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('C'), par exemple
229 if valeur.__class__.__name__ in ('EVAL','complexe'):
231 elif valeur.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
232 # il faut tester si la valeur du parametre est un entier
233 #XXX ne serait ce pas plutot complexe ???? sinon expliquer
234 return self.is_entier(valeur.valeur)
236 print "Objet non reconnu dans is_complexe %s" %`valeur`
238 elif type(valeur) != types.TupleType :
241 if len(valeur) != 3 :
244 if type(valeur[0]) != types.StringType : return 0
245 if string.strip(valeur[0]) not in ('RI','MP'):
248 if not self.is_reel(valeur[1]) or not self.is_reel(valeur[2]) : return 0
251 def is_reel(self,valeur):
253 Retourne 1 si valeur est un reel, 0 sinon
255 if type(valeur) == types.StringType :
256 # on teste une valeur issue d'une entry (valeur saisie depuis EFICAS)
257 if not self.jdc :return 0
259 valeur = eval(valeur,self.jdc.g_context)
262 if type(valeur) == types.InstanceType :
263 #XXX je n'y touche pas pour ne pas tout casser mais il serait
264 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('R'), par exemple
265 #XXX ou valeur.is_reel()
266 #XXX ou encore valeur.compare(self.is_reel)
267 if valeur.__class__.__name__ in ('EVAL','reel') :
269 elif valeur.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
270 # il faut tester si la valeur du parametre est un réel
271 return self.is_reel(valeur.valeur)
273 print "Objet non reconnu dans is_reel %s" %`valeur`
275 elif type(valeur) not in (types.IntType,types.FloatType,types.LongType):
276 # ce n'est pas un réel
281 def is_entier(self,valeur):
282 """ Retourne 1 si valeur est un entier, 0 sinon """
283 if type(valeur) == types.StringType :
284 # on teste une valeur issue d'une entry (valeur saisie depuis EFICAS)
285 if not self.jdc :return 0
287 valeur = eval(valeur,self.jdc.g_context)
290 if type(valeur) == types.InstanceType :
291 #XXX je n'y touche pas pour ne pas tout casser mais il serait
292 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('I'), par exemple
293 if valeur.__class__.__name__ in ('EVAL','entier') :
295 elif valeur.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
296 # il faut tester si la valeur du parametre est un entier
297 return self.is_entier(valeur.valeur)
299 print "Objet non reconnu dans is_reel %s" %`valeur`
301 elif type(valeur) not in (types.IntType,types.LongType):
302 # ce n'est pas un entier
307 def is_shell(self,valeur):
309 Retourne 1 si valeur est un shell, 0 sinon
310 Pour l'instant aucune vérification n'est faite
311 On impose juste que valeur soit une string
313 if type(valeur) != types.StringType:
318 def is_object_from(self,objet,classe):
320 Retourne 1 si valeur est un objet de la classe classe ou d'une sous-classe de classe,
323 if type(objet) != types.InstanceType :
324 if type(objet) == types.StringType:
325 if not self.jdc :return 0
327 objet = eval(objet,self.jdc.g_context)
328 if type(objet) != types.InstanceType : return 0
333 if not objet.__class__ == classe and not issubclass(objet.__class__,classe):
338 def compare_type(self,valeur,type_permis):
340 Fonction booléenne qui retourne 1 si valeur est du type type_permis, 0 sinon
342 if type(valeur) == types.InstanceType and valeur.__class__.__name__ == 'PARAMETRE':
343 if type(valeur.valeur) == types.TupleType :
344 # on a à faire à un PARAMETRE qui définit une liste d'items
345 # --> on teste sur la première car on n'accepte que les liste homogènes
346 valeur = valeur.valeur[0]
347 if type_permis == 'R':
348 return self.is_reel(valeur)
349 elif type_permis == 'I':
350 return self.is_entier(valeur)
351 elif type_permis == 'C':
352 return self.is_complexe(valeur)
353 elif type_permis == 'shell':
354 return self.is_shell(valeur)
355 elif type_permis == 'TXM':
356 if type(valeur) != types.InstanceType:
357 return type(valeur)==types.StringType
359 #XXX je n'y touche pas pour ne pas tout casser mais il serait
360 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('TXM'), par exemple
361 if valeur.__class__.__name__ == 'chaine' :
363 elif valeur.__class__.__name__ == 'PARAMETRE':
364 # il faut tester si la valeur du parametre est une string
365 return type(valeur.valeur)==types.StringType
368 elif type(type_permis) == types.ClassType:
369 # on ne teste pas certains objets de type GEOM , assd, ...
370 # On appelle la méthode de classe is_object de type_permis.
371 # Comme valeur peut etre de n'importe quel type on utilise la fonction (is_object.im_func)
372 # et non pas la methode (is_object) ce qui risquerait de provoquer des erreurs
373 if type_permis.is_object.im_func(valeur):
376 return self.is_object_from(valeur,type_permis)
378 print "Type non encore géré %s" %`type_permis`
379 print self.nom,self.parent.nom,self.jdc.fichier
381 def isinintervalle(self,valeur,cr='non'):
383 Booléenne qui retourne 1 si la valeur passée en argument est comprise dans
384 le domaine de définition donné dans le catalogue, 0 sinon.
386 if type(valeur) not in (types.IntType,types.FloatType,types.LongType) :
389 min = self.definition.val_min
390 max = self.definition.val_max
391 if min == '**': min = valeur -1
392 if max == '**': max = valeur +1
393 if valeur < min or valeur > max :
395 self.cr.fatal(string.join(("La valeur :",`valeur`," du mot-clé ",self.nom,\
396 " est en dehors du domaine de validité [",`min`,",",`max`,"]")))
401 def init_modif_up(self):
403 Propage l'état modifié au parent s'il existe et n'est l'objet
406 if self.parent and self.parent != self :
407 self.parent.state = 'modified'
410 """ génère le rapport de validation de self """
412 self.cr.debut = "Mot-clé simple : "+self.nom
413 self.cr.fin = "Fin Mot-clé simple : "+self.nom
414 self.state = 'modified'
416 self.isvalid(cr='oui')
417 except AsException,e:
418 if CONTEXT.debug : traceback.print_exc()
419 self.cr.fatal(string.join(("Mot-clé simple : ",self.nom,str(e))))