1 #@ MODIF V_MCSIMP Validation DATE 20/09/2004 AUTEUR DURAND C.DURAND
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.
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.
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.
21 # ======================================================================
24 Ce module contient la classe mixin MCSIMP qui porte les méthodes
25 nécessaires pour réaliser la validation d'un objet de type MCSIMP
28 Une classe mixin porte principalement des traitements et est
29 utilisée par héritage multiple pour composer les traitements.
36 from Noyau import N_CR
37 from Noyau.N_Exception import AsException
42 Cette classe est quasiment identique à la classe originale d'EFICAS
43 a part quelques changements cosmétiques et des chagements pour la
44 faire fonctionner de facon plus autonome par rapport à l'environnement
47 A mon avis, il faudrait aller plus loin et réduire les dépendances
48 amont au strict nécessaire.
50 - Est il indispensable de faire l'évaluation de la valeur dans le contexte
51 du jdc dans cette classe.
53 - Ne pourrait on pas doter les objets en présence des méthodes suffisantes
54 pour éviter les tests un peu particuliers sur GEOM, PARAMETRE et autres. J'ai
55 d'ailleurs modifié la classe pour éviter l'import de GEOM
61 self.state='undetermined'
64 if hasattr(self,'valid'):
70 def set_valid(self,valid):
71 old_valid=self.get_valid()
73 self.state = 'unchanged'
74 if not old_valid or old_valid != self.valid :
77 def isvalid(self,cr='non'):
79 Cette méthode retourne un indicateur de validité de l'objet de type MCSIMP
81 - 0 si l'objet est invalide
82 - 1 si l'objet est valide
84 Le paramètre cr permet de paramétrer le traitement. Si cr == 'oui'
85 la méthode construit également un comte-rendu de validation
86 dans self.cr qui doit avoir été créé préalablement.
88 if self.state == 'unchanged':
93 # verification presence
94 if self.isoblig() and v == None :
96 self.cr.fatal(string.join(("Mot-clé : ",self.nom," obligatoire non valorisé")))
102 self.cr.fatal("None n'est pas une valeur autorisée")
105 valid = self.verif_type(val=v,cr=cr)*self.verif_into(cr=cr)*self.verif_card(cr=cr)
107 # On verifie les validateurs s'il y en a et si necessaire (valid == 1)
109 if valid and self.definition.validators and not self.definition.validators.verif(self.valeur):
111 self.cr.fatal(string.join(("Mot-clé : ",self.nom,"devrait avoir ",self.definition.validators.info())))
113 # fin des validateurs
115 # cas d un item Parametre
116 if self.valeur.__class__.__name__ == 'ITEM_PARAMETRE':
117 valid=self.valeur.isvalid()
120 self.cr.fatal(string.join( repr (self.valeur), " a un indice incorrect"))
122 self.set_valid(valid)
126 """ indique si le mot-clé est obligatoire
128 return self.definition.statut=='o'
130 def verif_card(self,cr='non'):
132 un mot-clé simple ne peut etre répété :
133 la cardinalité ici s'entend par la vérification que le nombre d'arguments de self.valeur
134 est bien compris entre self.min et self.max dans le cas où il s'agit d'une liste
137 min=self.definition.min
138 max=self.definition.max
140 if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
141 length=len(self.valeur)
143 if self.valeur == None :
148 if length < min or length >max:
150 self.cr.fatal("Nombre d'arguments de %s incorrect pour %s (min = %s, max = %s)" %(`self.valeur`,self.nom,min,max))
154 def verif_type(self,val=None,cr='non'):
157 Cette methode verifie que le type de l'argument val est en conformite avec celui
158 qui est declare dans la definition du mot cle simple.
159 Elle a plusieurs modes de fonctionnement liés à la valeur de cr.
160 Si cr vaut 'oui' : elle remplit le compte-rendu self.cr sinon elle ne le remplit pas.
161 PARAMETRE DE RETOUR :
162 Cette méthode retourne une valeur booléenne qui vaut 1 si le type de val est correct ou 0 sinon
168 self.cr.fatal("None n'est pas une valeur autorisée")
171 if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
172 # Ici on a identifié une liste de valeurs
174 if not self.verif_type(val=val,cr=cr) : return 0
177 # Ici, valeur est un scalaire ...il faut tester sur tous les types ou les valeurs possibles
179 for type_permis in self.definition.type:
180 if self.compare_type(valeur,type_permis) : return 1
182 # 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
184 self.cr.fatal("%s n'est pas d'un type autorisé" %`valeur`)
187 def verif_into(self,cr='non'):
189 Vérifie si la valeur de self est bien dans l'ensemble discret de valeurs
190 donné dans le catalogue derrière l'attribut into ou vérifie que valeur est bien compris
191 entre val_min et val_max
193 if self.definition.into == None :
194 #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
195 if self.definition.val_min == '**' and self.definition.val_max == '**':
196 # L'intervalle est infini, on ne fait pas de test
198 #if type(self.valeur) in (types.ListType,types.TupleType) :
199 if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
200 # Cas d'une liste de valeurs
202 for val in self.valeur :
203 if type(val) != types.StringType and type(val) != types.InstanceType:
204 test = test*self.isinintervalle(val,cr=cr)
209 if type(val)!=types.StringType and type(val)!=types.InstanceType:
210 return self.isinintervalle(self.valeur,cr=cr)
214 # on est dans le cas d'un ensemble discret de valeurs possibles (into)
215 #if type(self.valeur) in (types.ListType,types.TupleType) :
216 if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
217 # Cas d'une liste de valeur
218 for e in self.valeur:
219 if e not in self.definition.into:
221 self.cr.fatal(string.join(("La valeur :",`e`," n'est pas permise pour le mot-clé :",self.nom)))
224 if self.valeur not in self.definition.into:
226 self.cr.fatal(string.join(("La valeur :",`self.valeur`," n'est pas permise pour le mot-clé :",self.nom)))
230 def is_complexe(self,valeur):
231 """ Retourne 1 si valeur est un complexe, 0 sinon """
232 if type(valeur) == types.InstanceType :
233 #XXX je n'y touche pas pour ne pas tout casser mais il serait
234 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('C'), par exemple
235 if valeur.__class__.__name__ in ('complexe','PARAMETRE_EVAL'):
237 elif valeur.__class__.__name__ in ('PARAMETRE',):
238 # il faut tester si la valeur du parametre est un complexe
239 return self.is_complexe(valeur.valeur)
242 # Pour permettre l'utilisation de complexes Python
243 #elif type(valeur) == types.ComplexType:
245 elif type(valeur) != types.TupleType :
246 # On n'autorise pas les listes pour les complexes
248 elif len(valeur) != 3:return 0
250 # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
251 # valeur suivie de 2 reels.
253 if string.strip(valeur[0]) in ('RI','MP') and self.is_reel(valeur[1]) and self.is_reel(valeur[2]):
258 def is_reel(self,valeur):
260 Retourne 1 si valeur est un reel, 0 sinon
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 ('reel','PARAMETRE_EVAL') :
269 elif valeur.__class__.__name__ in ('PARAMETRE',):
270 # il faut tester si la valeur du parametre est un réel
271 return self.is_reel(valeur.valeur)
274 elif type(valeur) not in (types.IntType,types.FloatType,types.LongType):
275 # ce n'est pas un réel
284 def is_entier(self,valeur):
285 """ Retourne 1 si valeur est un entier, 0 sinon """
286 if type(valeur) == types.InstanceType :
287 #XXX je n'y touche pas pour ne pas tout casser mais il serait
288 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('I'), par exemple
289 if valeur.__class__.__name__ in ('entier','PARAMETRE_EVAL') :
291 elif valeur.__class__.__name__ in ('PARAMETRE',):
292 # il faut tester si la valeur du parametre est un entier
293 return self.is_entier(valeur.valeur)
296 elif type(valeur) not in (types.IntType,types.LongType):
297 # ce n'est pas un entier
302 def is_shell(self,valeur):
304 Retourne 1 si valeur est un shell, 0 sinon
305 Pour l'instant aucune vérification n'est faite
306 On impose juste que valeur soit une string
308 if type(valeur) != types.StringType:
313 def is_object_from(self,objet,classe):
315 Retourne 1 si valeur est un objet de la classe classe ou d'une
316 sous-classe de classe, 0 sinon
318 if type(objet) != types.InstanceType :
320 if not objet.__class__ == classe and not issubclass(objet.__class__,classe):
325 def compare_type(self,valeur,type_permis):
327 Fonction booléenne qui retourne 1 si valeur est du type type_permis, 0 sinon
329 if type(valeur) == types.InstanceType and valeur.__class__.__name__ == 'PARAMETRE':
330 if type(valeur.valeur) == types.TupleType :
331 # on a à faire à un PARAMETRE qui définit une liste d'items
332 # --> on teste sur la première car on n'accepte que les liste homogènes
333 valeur = valeur.valeur[0]
335 if valeur.__class__.__name__ == 'PARAMETRE' or valeur.__class__.__name__ == 'ITEM_PARAMETRE':
336 # on admet que c'est OK
339 if type_permis == 'R':
340 return self.is_reel(valeur)
341 elif type_permis == 'I':
342 return self.is_entier(valeur)
343 elif type_permis == 'C':
344 return self.is_complexe(valeur)
345 elif type_permis == 'shell':
346 return self.is_shell(valeur)
347 elif type_permis == 'TXM':
348 if type(valeur) != types.InstanceType:
349 return type(valeur)==types.StringType
351 #XXX je n'y touche pas pour ne pas tout casser mais il serait
352 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('TXM'), par exemple
353 if valeur.__class__.__name__ == 'chaine' :
355 elif valeur.__class__.__name__ == 'PARAMETRE':
356 # il faut tester si la valeur du parametre est une string
357 return type(valeur.valeur)==types.StringType
360 elif type(type_permis) == types.ClassType:
361 # on ne teste pas certains objets de type GEOM , assd, ...
362 # On appelle la méthode de classe is_object de type_permis.
363 # Comme valeur peut etre de n'importe quel type on utilise la fonction (is_object.im_func)
364 # et non pas la methode (is_object) ce qui risquerait de provoquer des erreurs
365 if type_permis.is_object.im_func(valeur):
368 return self.is_object_from(valeur,type_permis)
370 print "Type non encore géré %s" %`type_permis`
371 print self.nom,self.parent.nom,self.jdc.fichier
373 def isinintervalle(self,valeur,cr='non'):
375 Booléenne qui retourne 1 si la valeur passée en argument est comprise dans
376 le domaine de définition donné dans le catalogue, 0 sinon.
378 if type(valeur) not in (types.IntType,types.FloatType,types.LongType) :
381 min = self.definition.val_min
382 max = self.definition.val_max
383 if min == '**': min = valeur -1
384 if max == '**': max = valeur +1
385 if valeur < min or valeur > max :
387 self.cr.fatal(string.join(("La valeur :",`valeur`," du mot-clé ",self.nom,\
388 " est en dehors du domaine de validité [",`min`,",",`max`,"]")))
393 def init_modif_up(self):
395 Propage l'état modifié au parent s'il existe et n'est l'objet
398 if self.parent and self.parent != self :
399 self.parent.state = 'modified'
402 """ génère le rapport de validation de self """
404 self.cr.debut = "Mot-clé simple : "+self.nom
405 self.cr.fin = "Fin Mot-clé simple : "+self.nom
406 self.state = 'modified'
408 self.isvalid(cr='oui')
409 except AsException,e:
410 if CONTEXT.debug : traceback.print_exc()
411 self.cr.fatal(string.join(("Mot-clé simple : ",self.nom,str(e))))