1 #@ MODIF V_MCSIMP Validation DATE 06/10/2003 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'
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)
104 valid = self.verif_type(val=v,cr=cr)
105 valid=valid*self.verif_into(cr=cr)
106 valid=valid*self.verif_card(cr=cr)
108 # On verifie les validateurs s'il y en a et si necessaire (valid == 1)
110 if valid and self.definition.validators and not self.definition.validators.verif(self.valeur):
112 self.cr.fatal(string.join(("Mot-clé : ",self.nom,"devrait avoir ",self.definition.validators.info())))
114 # fin des validateurs
117 self.set_valid(valid)
121 """ indique si le mot-clé est obligatoire
123 return self.definition.statut=='o'
125 def verif_card(self,cr='non'):
127 un mot-clé simple ne peut etre répété :
128 la cardinalité ici s'entend par la vérification que le nombre d'arguments de self.valeur
129 est bien compris entre self.min et self.max dans le cas où il s'agit d'une liste
132 min=self.definition.min
133 max=self.definition.max
135 if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
136 length=len(self.valeur)
138 if self.valeur == None :
143 if length < min or length >max:
145 self.cr.fatal("Nombre d'arguments de %s incorrect pour %s (min = %s, max = %s)" %(`self.valeur`,self.nom,min,max))
149 def verif_type(self,val=None,cr='non'):
152 Cette methode verifie que le type de l'argument val est en conformite avec celui
153 qui est declare dans la definition du mot cle simple.
154 Elle a plusieurs modes de fonctionnement liés à la valeur de cr.
155 Si cr vaut 'oui' : elle remplit le compte-rendu self.cr sinon elle ne le remplit pas.
156 PARAMETRE DE RETOUR :
157 Cette méthode retourne une valeur booléenne qui vaut 1 si le type de val est correct ou 0 sinon
163 self.cr.fatal("None n'est pas une valeur autorisée")
166 if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
167 # Ici on a identifié une liste de valeurs
169 if not self.verif_type(val=val,cr=cr) : return 0
172 # Ici, valeur est un scalaire ...il faut tester sur tous les types ou les valeurs possibles
174 for type_permis in self.definition.type:
175 if self.compare_type(valeur,type_permis) : return 1
177 # 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
179 self.cr.fatal("%s n'est pas d'un type autorisé" %`valeur`)
182 def verif_into(self,cr='non'):
184 Vérifie si la valeur de self est bien dans l'ensemble discret de valeurs
185 donné dans le catalogue derrière l'attribut into ou vérifie que valeur est bien compris
186 entre val_min et val_max
188 if self.definition.into == None :
189 #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
190 if self.definition.val_min == '**' and self.definition.val_max == '**':
191 # L'intervalle est infini, on ne fait pas de test
193 #if type(self.valeur) in (types.ListType,types.TupleType) :
194 if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
195 # Cas d'une liste de valeurs
197 for val in self.valeur :
198 if type(val) != types.StringType and type(val) != types.InstanceType:
199 test = test*self.isinintervalle(val,cr=cr)
204 if type(val)!=types.StringType and type(val)!=types.InstanceType:
205 return self.isinintervalle(self.valeur,cr=cr)
209 # on est dans le cas d'un ensemble discret de valeurs possibles (into)
210 #if type(self.valeur) in (types.ListType,types.TupleType) :
211 if type(self.valeur) == types.TupleType and not self.valeur[0] in ('RI','MP') or type(self.valeur) == types.ListType:
212 # Cas d'une liste de valeur
213 for e in self.valeur:
214 if e not in self.definition.into:
216 self.cr.fatal(string.join(("La valeur :",`e`," n'est pas permise pour le mot-clé :",self.nom)))
219 if self.valeur not in self.definition.into:
221 self.cr.fatal(string.join(("La valeur :",`self.valeur`," n'est pas permise pour le mot-clé :",self.nom)))
225 def is_complexe(self,valeur):
226 """ Retourne 1 si valeur est un complexe, 0 sinon """
227 if type(valeur) == types.InstanceType :
228 #XXX je n'y touche pas pour ne pas tout casser mais il serait
229 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('C'), par exemple
230 if valeur.__class__.__name__ in ('EVAL','complexe','PARAMETRE_EVAL'):
232 elif valeur.__class__.__name__ in ('PARAMETRE',):
233 # il faut tester si la valeur du parametre est un complexe
234 return self.is_complexe(valeur.valeur)
236 print "Objet non reconnu dans is_complexe %s" %`valeur`
238 # Pour permettre l'utilisation de complexes Python
239 #elif type(valeur) == types.ComplexType:
241 elif type(valeur) != types.TupleType :
242 # On n'autorise pas les listes pour les complexes
244 elif len(valeur) != 3:return 0
246 # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
247 # valeur suivie de 2 reels.
249 if string.strip(valeur[0]) in ('RI','MP') and self.is_reel(valeur[1]) and self.is_reel(valeur[2]):
254 def is_reel(self,valeur):
256 Retourne 1 si valeur est un reel, 0 sinon
258 if type(valeur) == types.InstanceType :
259 #XXX je n'y touche pas pour ne pas tout casser mais il serait
260 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('R'), par exemple
261 #XXX ou valeur.is_reel()
262 #XXX ou encore valeur.compare(self.is_reel)
263 if valeur.__class__.__name__ in ('EVAL','reel','PARAMETRE_EVAL') :
265 elif valeur.__class__.__name__ in ('PARAMETRE',):
266 # il faut tester si la valeur du parametre est un réel
267 return self.is_reel(valeur.valeur)
269 print "Objet non reconnu dans is_reel %s" %`valeur`
271 elif type(valeur) not in (types.IntType,types.FloatType,types.LongType):
272 # ce n'est pas un réel
277 def is_entier(self,valeur):
278 """ Retourne 1 si valeur est un entier, 0 sinon """
279 if type(valeur) == types.InstanceType :
280 #XXX je n'y touche pas pour ne pas tout casser mais il serait
281 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('I'), par exemple
282 if valeur.__class__.__name__ in ('EVAL','entier','PARAMETRE_EVAL') :
284 elif valeur.__class__.__name__ in ('PARAMETRE',):
285 # il faut tester si la valeur du parametre est un entier
286 return self.is_entier(valeur.valeur)
288 print "Objet non reconnu dans is_reel %s" %`valeur`
290 elif type(valeur) not in (types.IntType,types.LongType):
291 # ce n'est pas un entier
296 def is_shell(self,valeur):
298 Retourne 1 si valeur est un shell, 0 sinon
299 Pour l'instant aucune vérification n'est faite
300 On impose juste que valeur soit une string
302 if type(valeur) != types.StringType:
307 def is_object_from(self,objet,classe):
309 Retourne 1 si valeur est un objet de la classe classe ou d'une
310 sous-classe de classe, 0 sinon
312 if type(objet) != types.InstanceType :
314 if not objet.__class__ == classe and not issubclass(objet.__class__,classe):
319 def compare_type(self,valeur,type_permis):
321 Fonction booléenne qui retourne 1 si valeur est du type type_permis, 0 sinon
323 if type(valeur) == types.InstanceType and valeur.__class__.__name__ == 'PARAMETRE':
324 if type(valeur.valeur) == types.TupleType :
325 # on a à faire à un PARAMETRE qui définit une liste d'items
326 # --> on teste sur la première car on n'accepte que les liste homogènes
327 valeur = valeur.valeur[0]
328 if type_permis == 'R':
329 return self.is_reel(valeur)
330 elif type_permis == 'I':
331 return self.is_entier(valeur)
332 elif type_permis == 'C':
333 return self.is_complexe(valeur)
334 elif type_permis == 'shell':
335 return self.is_shell(valeur)
336 elif type_permis == 'TXM':
337 if type(valeur) != types.InstanceType:
338 return type(valeur)==types.StringType
340 #XXX je n'y touche pas pour ne pas tout casser mais il serait
341 #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('TXM'), par exemple
342 if valeur.__class__.__name__ == 'chaine' :
344 elif valeur.__class__.__name__ == 'PARAMETRE':
345 # il faut tester si la valeur du parametre est une string
346 return type(valeur.valeur)==types.StringType
349 elif type(type_permis) == types.ClassType:
350 # on ne teste pas certains objets de type GEOM , assd, ...
351 # On appelle la méthode de classe is_object de type_permis.
352 # Comme valeur peut etre de n'importe quel type on utilise la fonction (is_object.im_func)
353 # et non pas la methode (is_object) ce qui risquerait de provoquer des erreurs
354 if type_permis.is_object.im_func(valeur):
357 return self.is_object_from(valeur,type_permis)
359 print "Type non encore géré %s" %`type_permis`
360 print self.nom,self.parent.nom,self.jdc.fichier
362 def isinintervalle(self,valeur,cr='non'):
364 Booléenne qui retourne 1 si la valeur passée en argument est comprise dans
365 le domaine de définition donné dans le catalogue, 0 sinon.
367 if type(valeur) not in (types.IntType,types.FloatType,types.LongType) :
370 min = self.definition.val_min
371 max = self.definition.val_max
372 if min == '**': min = valeur -1
373 if max == '**': max = valeur +1
374 if valeur < min or valeur > max :
376 self.cr.fatal(string.join(("La valeur :",`valeur`," du mot-clé ",self.nom,\
377 " est en dehors du domaine de validité [",`min`,",",`max`,"]")))
382 def init_modif_up(self):
384 Propage l'état modifié au parent s'il existe et n'est l'objet
387 if self.parent and self.parent != self :
388 self.parent.state = 'modified'
391 """ génère le rapport de validation de self """
393 self.cr.debut = "Mot-clé simple : "+self.nom
394 self.cr.fin = "Fin Mot-clé simple : "+self.nom
395 self.state = 'modified'
397 self.isvalid(cr='oui')
398 except AsException,e:
399 if CONTEXT.debug : traceback.print_exc()
400 self.cr.fatal(string.join(("Mot-clé simple : ",self.nom,str(e))))