1 #@ MODIF V_MCSIMP Validation DATE 04/02/2004 AUTEUR CAMBIER S.CAMBIER
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'
62 if hasattr(self,'valid'):
68 def set_valid(self,valid):
69 old_valid=self.get_valid()
71 self.state = 'unchanged'
72 if not old_valid or old_valid != self.valid :
75 def isvalid(self,cr='non'):
77 Cette méthode retourne un indicateur de validité de l'objet de type MCSIMP
79 - 0 si l'objet est invalide
80 - 1 si l'objet est valide
82 Le paramètre cr permet de paramétrer le traitement. Si cr == 'oui'
83 la méthode construit également un comte-rendu de validation
84 dans self.cr qui doit avoir été créé préalablement.
86 if self.state == 'unchanged':
91 # verification presence
92 if self.isoblig() and v == None :
94 self.cr.fatal(string.join(("Mot-clé : ",self.nom," obligatoire non valorisé")))
100 self.cr.fatal("None n'est pas une valeur autorisée")
103 valid = self.verif_type(val=v,cr=cr)*self.verif_into(cr=cr)*self.verif_card(cr=cr)
105 # On verifie les validateurs s'il y en a et si necessaire (valid == 1)
107 if valid and self.definition.validators and not self.definition.validators.verif(self.valeur):
109 self.cr.fatal(string.join(("Mot-clé : ",self.nom,"devrait avoir ",self.definition.validators.info())))
111 # fin des validateurs
114 self.set_valid(valid)
118 """ indique si le mot-clé est obligatoire
120 return self.definition.statut=='o'
122 def verif_card(self,cr='non'):
124 un mot-clé simple ne peut etre répété :
125 la cardinalité ici s'entend par la vérification que le nombre d'arguments de self.valeur
126 est bien compris entre self.min et self.max dans le cas où il s'agit d'une liste
129 min=self.definition.min
130 max=self.definition.max
132 if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
133 length=len(self.valeur)
135 if self.valeur == None :
140 if length < min or length >max:
142 self.cr.fatal("Nombre d'arguments de %s incorrect pour %s (min = %s, max = %s)" %(`self.valeur`,self.nom,min,max))
146 def verif_type(self,val=None,cr='non'):
149 Cette methode verifie que le type de l'argument val est en conformite avec celui
150 qui est declare dans la definition du mot cle simple.
151 Elle a plusieurs modes de fonctionnement liés à la valeur de cr.
152 Si cr vaut 'oui' : elle remplit le compte-rendu self.cr sinon elle ne le remplit pas.
153 PARAMETRE DE RETOUR :
154 Cette méthode retourne une valeur booléenne qui vaut 1 si le type de val est correct ou 0 sinon
160 self.cr.fatal("None n'est pas une valeur autorisée")
163 if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
164 # Ici on a identifié une liste de valeurs
166 if not self.verif_type(val=val,cr=cr) : return 0
169 # Ici, valeur est un scalaire ...il faut tester sur tous les types ou les valeurs possibles
171 for type_permis in self.definition.type:
172 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 self.definition.val_min == '**' and self.definition.val_max == '**':
188 # L'intervalle est infini, on ne fait pas de test
190 #if type(self.valeur) in (types.ListType,types.TupleType) :
191 if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
192 # Cas d'une liste de valeurs
194 for val in self.valeur :
195 if type(val) != types.StringType and type(val) != types.InstanceType:
196 test = test*self.isinintervalle(val,cr=cr)
201 if type(val)!=types.StringType and type(val)!=types.InstanceType:
202 return self.isinintervalle(self.valeur,cr=cr)
206 # on est dans le cas d'un ensemble discret de valeurs possibles (into)
207 #if type(self.valeur) in (types.ListType,types.TupleType) :
208 if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
209 # Cas d'une liste de valeur
210 for e in self.valeur:
211 if e not in self.definition.into:
213 self.cr.fatal(string.join(("La valeur :",`e`," n'est pas permise pour le mot-clé :",self.nom)))
216 if self.valeur not in self.definition.into:
218 self.cr.fatal(string.join(("La valeur :",`self.valeur`," n'est pas permise pour le mot-clé :",self.nom)))
222 def is_complexe(self,valeur):
223 """ Retourne 1 si valeur est un complexe, 0 sinon """
224 if type(valeur) == types.InstanceType :
225 #XXX je n'y touche pas pour ne pas tout casser mais il serait
226 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('C'), par exemple
227 if valeur.__class__.__name__ in ('EVAL','complexe','PARAMETRE_EVAL'):
229 elif valeur.__class__.__name__ in ('PARAMETRE',):
230 # il faut tester si la valeur du parametre est un complexe
231 return self.is_complexe(valeur.valeur)
233 print "Objet non reconnu dans is_complexe %s" %`valeur`
235 # Pour permettre l'utilisation de complexes Python
236 #elif type(valeur) == types.ComplexType:
238 elif type(valeur) != types.TupleType :
239 # On n'autorise pas les listes pour les complexes
241 elif len(valeur) != 3:return 0
243 # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
244 # valeur suivie de 2 reels.
246 if string.strip(valeur[0]) in ('RI','MP') and self.is_reel(valeur[1]) and self.is_reel(valeur[2]):
251 def is_reel(self,valeur):
253 Retourne 1 si valeur est un reel, 0 sinon
255 if type(valeur) == types.InstanceType :
256 #XXX je n'y touche pas pour ne pas tout casser mais il serait
257 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('R'), par exemple
258 #XXX ou valeur.is_reel()
259 #XXX ou encore valeur.compare(self.is_reel)
260 if valeur.__class__.__name__ in ('EVAL','reel','PARAMETRE_EVAL') :
262 elif valeur.__class__.__name__ in ('PARAMETRE',):
263 # il faut tester si la valeur du parametre est un réel
264 return self.is_reel(valeur.valeur)
266 print "Objet non reconnu dans is_reel %s" %`valeur`
268 elif type(valeur) not in (types.IntType,types.FloatType,types.LongType):
269 # ce n'est pas un réel
274 def is_entier(self,valeur):
275 """ Retourne 1 si valeur est un entier, 0 sinon """
276 if type(valeur) == types.InstanceType :
277 #XXX je n'y touche pas pour ne pas tout casser mais il serait
278 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('I'), par exemple
279 if valeur.__class__.__name__ in ('EVAL','entier','PARAMETRE_EVAL') :
281 elif valeur.__class__.__name__ in ('PARAMETRE',):
282 # il faut tester si la valeur du parametre est un entier
283 return self.is_entier(valeur.valeur)
285 print "Objet non reconnu dans is_reel %s" %`valeur`
287 elif type(valeur) not in (types.IntType,types.LongType):
288 # ce n'est pas un entier
293 def is_shell(self,valeur):
295 Retourne 1 si valeur est un shell, 0 sinon
296 Pour l'instant aucune vérification n'est faite
297 On impose juste que valeur soit une string
299 if type(valeur) != types.StringType:
304 def is_object_from(self,objet,classe):
306 Retourne 1 si valeur est un objet de la classe classe ou d'une
307 sous-classe de classe, 0 sinon
309 if type(objet) != types.InstanceType :
311 if not objet.__class__ == classe and not issubclass(objet.__class__,classe):
316 def compare_type(self,valeur,type_permis):
318 Fonction booléenne qui retourne 1 si valeur est du type type_permis, 0 sinon
320 if type(valeur) == types.InstanceType and valeur.__class__.__name__ == 'PARAMETRE':
321 if type(valeur.valeur) == types.TupleType :
322 # on a à faire à un PARAMETRE qui définit une liste d'items
323 # --> on teste sur la première car on n'accepte que les liste homogènes
324 valeur = valeur.valeur[0]
325 if type_permis == 'R':
326 return self.is_reel(valeur)
327 elif type_permis == 'I':
328 return self.is_entier(valeur)
329 elif type_permis == 'C':
330 return self.is_complexe(valeur)
331 elif type_permis == 'shell':
332 return self.is_shell(valeur)
333 elif type_permis == 'TXM':
334 if type(valeur) != types.InstanceType:
335 return type(valeur)==types.StringType
337 #XXX je n'y touche pas pour ne pas tout casser mais il serait
338 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('TXM'), par exemple
339 if valeur.__class__.__name__ == 'chaine' :
341 elif valeur.__class__.__name__ == 'PARAMETRE':
342 # il faut tester si la valeur du parametre est une string
343 return type(valeur.valeur)==types.StringType
346 elif type(type_permis) == types.ClassType:
347 # on ne teste pas certains objets de type GEOM , assd, ...
348 # On appelle la méthode de classe is_object de type_permis.
349 # Comme valeur peut etre de n'importe quel type on utilise la fonction (is_object.im_func)
350 # et non pas la methode (is_object) ce qui risquerait de provoquer des erreurs
351 if type_permis.is_object.im_func(valeur):
354 return self.is_object_from(valeur,type_permis)
356 print "Type non encore géré %s" %`type_permis`
357 print self.nom,self.parent.nom,self.jdc.fichier
359 def isinintervalle(self,valeur,cr='non'):
361 Booléenne qui retourne 1 si la valeur passée en argument est comprise dans
362 le domaine de définition donné dans le catalogue, 0 sinon.
364 if type(valeur) not in (types.IntType,types.FloatType,types.LongType) :
367 min = self.definition.val_min
368 max = self.definition.val_max
369 if min == '**': min = valeur -1
370 if max == '**': max = valeur +1
371 if valeur < min or valeur > max :
373 self.cr.fatal(string.join(("La valeur :",`valeur`," du mot-clé ",self.nom,\
374 " est en dehors du domaine de validité [",`min`,",",`max`,"]")))
379 def init_modif_up(self):
381 Propage l'état modifié au parent s'il existe et n'est l'objet
384 if self.parent and self.parent != self :
385 self.parent.state = 'modified'
388 """ génère le rapport de validation de self """
390 self.cr.debut = "Mot-clé simple : "+self.nom
391 self.cr.fin = "Fin Mot-clé simple : "+self.nom
392 self.state = 'modified'
394 self.isvalid(cr='oui')
395 except AsException,e:
396 if CONTEXT.debug : traceback.print_exc()
397 self.cr.fatal(string.join(("Mot-clé simple : ",self.nom,str(e))))