Salome HOME
Import dans la branche I26 de la version 7.1.16 modifiée par CCAR (au 18/9/2003)
[tools/eficas.git] / Noyau / N_VALIDATOR.py
1 #@ MODIF N_VALIDATOR Noyau  DATE 09/09/2003   AUTEUR DURAND C.DURAND 
2 #            CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2003  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.                                                  
9 #                                                                       
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.                              
14 #                                                                       
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.        
18 # ======================================================================
19 """
20    Ce module contient toutes les classes necessaires pour
21    implanter le concept de validateur dans Accas
22 """
23 import types,exceptions
24
25 class ValError ( exceptions.Exception ):
26       pass
27
28 class Valid:
29    """
30         Cette classe est la classe mere des validateurs Accas
31         Elle doit etre derivee 
32         Elle ne presente que la signature des methodes
33         indispensables pour son bon fonctionnement
34
35         @ivar cata_info: raison de la validite ou de l'invalidite du validateur meme
36         @type cata_info: C{string}
37    """
38    def __init__(self,*tup,**args):
39        """ 
40            Cette methode sert a initialiser les attributs du validateur 
41        """
42        self.cata_info=""
43        raise "Must be implemented"
44
45    def info(self):
46        return "valeur valide" 
47
48    def verif(self,valeur):
49        """
50            Cette methode sert a verifier si la valeur passee en argument est consideree
51            comme valide ou non par le validateur. Dans le premier cas le validateur retourne 1
52            (valide) sinon 0 (invalide).
53
54            @type valeur: tout type python
55            @param valeur: valeur du mot cle a valider
56            @rtype: C{boolean}
57            @return: indicateur de validite 1 (valide) ou 0 (invalide)
58        """
59        raise "Must be implemented"
60    
61    def error(self,valeur):
62        return 0
63
64    def verif_cata(self):
65        """
66            Cette methode sert a realiser des verifications du validateur lui meme.
67            Elle est facultative et retourne 1 (valide) par defaut.
68            Elle retourne 0 si le validateur est lui meme invalide si par exemple ses
69            parametres de definition ne sont pas corrects.
70            La raison de l'invalidite est stockee dans l'attribut cata_info.
71
72            @rtype: C{boolean}
73            @return: indicateur de validite 1 (valide) ou 0 (invalide)
74        """
75        return 1
76
77 class RangeVal(Valid):
78       """
79           Exemple de classe validateur : verification qu'une valeur
80           est dans un intervalle.
81           Pour une liste on verifie que tous les elements sont 
82           dans l'intervalle
83           Susceptible de remplacer les attributs "vale_min" "vale_max"
84           dans les catalogues
85       """
86       def __init__(self,low,high):
87           self.low=low
88           self.high=high
89           self.cata_info="%s doit etre inferieur a %s" %(low,high)
90
91       def info(self):
92           return "valeur dans l'intervalle %s , %s" %(self.low,self.high)
93
94       def verif(self,valeur):
95           if type(valeur) in (types.ListType,types.TupleType):
96              for val in valeur:
97                 if val < self.low :return 0
98                 if val > self.high:return 0
99              return 1
100           else:
101              if valeur < self.low :return 0
102              if valeur > self.high:return 0
103              return 1
104
105       def verif_cata(self):
106           if self.low > self.high : return 0
107           return 1
108
109 class CardVal(Valid):
110       """
111           Exemple de classe validateur : verification qu'une liste est
112           d'une longueur superieur a un minimum (min) et inferieure
113           a un maximum (max).
114           Susceptible de remplacer les attributs "min" "max" dans les
115           catalogues
116       """
117       def __init__(self,min='**',max='**'):
118           self.min=min
119           self.max=max  
120           self.cata_info="%s doit etre inferieur a %s" % (min,max)
121
122       def info(self):
123           return "longueur comprise entre  %s et %s" % (self.min,self.max)
124
125       def verif(self,valeur):
126           if type(valeur) in (types.ListType,types.TupleType):
127              if self.max != '**' and len(valeur) > self.max:return 0
128              if self.min != '**' and len(valeur) < self.min:return 0
129              return 1
130           else:
131              if self.max != '**' and 1 > self.max:return 0
132              if self.min != '**' and 1 < self.min:return 0
133              return 1
134
135       def verif_cata(self):
136           if self.min != '**' and self.max != '**' and self.min > self.max : return 0
137           return 1
138
139 class PairVal(Valid):
140       """
141           Exemple de classe validateur : verification qu'une valeur
142           est paire.
143           Pour une liste on verifie que tous les elements sont
144           pairs
145       """
146       def __init__(self):
147           self.cata_info=""
148
149       def info(self):
150           return "valeur paire"
151
152       def verif(self,valeur):
153           if type(valeur) in (types.ListType,types.TupleType):
154              for val in valeur:
155                 if val % 2 != 0:return 0
156              return 1
157           else:
158              if valeur % 2 != 0:return 0
159              return 1
160
161 class EnumVal(Valid):
162       """
163           Exemple de classe validateur : verification qu'une valeur
164           est prise dans une liste de valeurs.
165           Susceptible de remplacer l attribut "into" dans les catalogues
166       """
167       def __init__(self,into=()):
168           if type(into) not in (types.ListType,types.TupleType): into=(into,)
169           self.into=into
170           self.cata_info=""
171
172       def info(self):
173           return "valeur dans %s" % `self.into`
174
175       def verif(self,valeur):
176           if type(valeur) in (types.ListType,types.TupleType):
177              for val in valeur:
178                 if val not in self.into:return 0
179              return 1
180           else:
181              if valeur not in self.into:return 0
182              return 1
183
184 class NoRepeat(Valid):
185       """
186           Verification d'absence de doublons dans la liste.
187       """
188       def __init__(self):
189           self.cata_info=""
190
191       def info(self):
192           return ": présence de doublon dans la liste"
193
194       def verif(self,valeur):
195           if type(valeur) in (types.ListType,types.TupleType):
196              liste=list(valeur)
197              for val in liste:
198                 if liste.count(val)!=1 : return 0
199              return 1
200           else:
201              return 1
202
203 class LongStr(Valid):
204       """
205           Verification de la longueur d une chaine
206       """
207       def __init__(self,low,high):
208           self.low=low
209           self.high=high
210           self.cata_info=""
211
212       def info(self):
213           return "longueur de la chaine entre %s et %s" %(self.low,self.high)
214
215       def verif(self,valeur):
216           if type(valeur) in (types.ListType,types.TupleType):
217              for val in valeur:
218                 if len(val) < self.low :return 0
219                 if len(val) > self.high:return 0
220              return 1
221           else:
222              if len(valeur) < self.low :return 0
223              if len(valeur) > self.high:return 0
224              return 1
225
226 class OrdList(Valid):
227       """
228           Verification qu'une liste est croissante ou decroissante
229       """
230       def __init__(self,ord):
231           self.ord=ord
232           self.cata_info=""
233
234       def info(self):
235           return "liste %s" % self.ord
236
237       def verif(self,valeur):
238           if type(valeur) in (types.ListType,types.TupleType):
239              if self.ord=='croissant':
240                 var=valeur[0]
241                 for val in valeur[1:]:
242                    if val<var:return 0
243                    var=val
244                 return 1
245              elif self.ord=='decroissant':
246                 var=valeur[0]
247                 for val in valeur[1:]:
248                    if val>var:return 0
249                    var=val
250                 return 1
251           else:
252              return 1
253
254
255 CoercableFuncs = { types.IntType:     int,
256                    types.LongType:    long,
257                    types.FloatType:   float,
258                    types.ComplexType: complex,
259                    types.UnicodeType: unicode }
260
261 class TypeVal(Valid):
262       """
263           Cette classe est un validateur qui controle qu'une valeur
264           est bien du type Python attendu.
265           Pour une liste on verifie que tous les elements sont du bon type.
266       """
267       def __init__(self, aType):
268           if type(aType) != types.TypeType:
269              aType=type(aType)
270           self.aType=aType
271           try:
272              self.coerce=CoercableFuncs[ aType ]
273           except:
274              self.coerce = self.identity
275
276       def info(self):
277           return "valeur de %s" % self.aType
278
279       def identity ( self, value ):
280           if type( value ) == self.aType:
281              return value
282           raise ValError
283
284       def verif(self,valeur):
285           if type(valeur) in (types.ListType,types.TupleType):
286              for val in valeur:
287                  try:
288                     self.coerce(val)
289                  except:
290                     return 0
291              return 1
292           else:
293              try:
294                 self.coerce(valeur)
295              except:
296                 return 0
297              return 1
298
299 class InstanceVal(Valid):
300       """
301           Cette classe est un validateur qui controle qu'une valeur est
302           bien une instance (au sens Python) d'une classe
303           Pour une liste on verifie chaque element de la liste
304       """
305       def __init__(self,aClass):
306           if type(aClass) == types.InstanceType:
307              aClass=aClass.__class__
308           self.aClass=aClass
309
310       def info(self):
311           return "valeur d'instance de %s" % self.aClass.__name__
312
313       def verif(self,valeur):
314           if type(valeur) in (types.ListType,types.TupleType):
315              for val in valeur:
316                  if not isinstance(val,self.aClass): return 0
317              return 1
318           if not isinstance(valeur,self.aClass): return 0
319           return 1
320
321 def ImpairVal(valeur):
322     """
323         Cette fonction est un validateur. Elle verifie que la valeur passee
324         est bien un nombre impair.
325     """
326     if type(valeur) in (types.ListType,types.TupleType):
327        for val in valeur:
328            if val % 2 != 1:return 0
329        return 1
330     else:
331        if valeur % 2 != 1:return 0
332        return 1
333
334 ImpairVal.info="valeur impaire"
335     
336 class F1Val(Valid):
337       """
338           Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie
339           que la somme des cles A et B vaut une valeur donnee
340           en parametre du validateur
341       """
342       def __init__(self,somme=10):
343           self.somme=somme
344           self.cata_info=""
345
346       def info(self):
347           return "valeur %s pour la somme des cles A et B " % self.somme
348
349       def verif(self,valeur):
350           if type(valeur) in (types.ListType,types.TupleType):
351              for val in valeur:
352                 if not val.has_key("A"):return 0
353                 if not val.has_key("B"):return 0
354                 if val["A"]+val["B"]  != self.somme:return 0
355              return 1
356           else:
357              if not valeur.has_key("A"):return 0
358              if not valeur.has_key("B"):return 0
359              if valeur["A"]+valeur["B"]  != self.somme:return 0
360              return 1
361
362 class FunctionVal(Valid):
363       """
364           Cette classe est un validateur qui est initialise avec une fonction
365       """
366       def __init__(self,function):
367           self.function=function
368
369       def info(self):
370           return self.function.info
371
372       def verif(self,valeur):
373           return self.function(valeur)
374
375 class OrVal(Valid):
376       """
377           Cette classe est un validateur qui controle une liste de validateurs
378           Elle verifie qu'au moins un des validateurs de la liste a valide la valeur
379       """
380       def __init__(self,validators=()):
381           if type(validators) not in (types.ListType,types.TupleType): validators=(validators,)
382           self.validators=[]
383           for validator in validators:
384               if type(validator) == types.FunctionType:
385                  self.validators.append(FunctionVal(validator))
386               else:
387                  self.validators.append(validator)
388           self.cata_info=""
389
390       def info(self):
391           return "\n ou ".join([v.info() for v in self.validators])
392
393       def verif(self,valeur):
394           for validator in self.validators:
395               v=validator.verif(valeur)
396               if v :
397                  return 1
398           return 0
399
400       def verif_cata(self):
401           infos=[]
402           for validator in self.validators:
403               v=validator.verif_cata()
404               if not v :infos.append(validator.cata_info)
405           if infos:
406              self.cata_info="\n".join(infos)
407              return 0
408           self.cata_info=""
409           return 1
410
411 class AndVal(Valid):
412       """
413           Cette classe est un validateur qui controle une liste de validateurs
414           Elle verifie que tous les validateurs de la liste sont positifs
415       """
416       def __init__(self,validators=()):
417           if type(validators) not in (types.ListType,types.TupleType): validators=(validators,)
418           self.validators=[]
419           for validator in validators:
420               if type(validator) == types.FunctionType:
421                  self.validators.append(FunctionVal(validator))
422               else:
423                  self.validators.append(validator)
424           self.cata_info=""
425
426       def info(self):
427           return " et ".join([v.info() for v in self.validators])
428
429       def verif(self,valeur):
430           for validator in self.validators:
431               v=validator.verif(valeur)
432               if not v :
433                  self.local_info=validator.info()
434                  return 0
435           return 1
436
437       def verif_cata(self):
438           infos=[]
439           for validator in self.validators:
440               v=validator.verif_cata()
441               if not v :infos.append(validator.cata_info)
442           if infos:
443              self.cata_info="\n".join(infos)
444              return 0
445           self.cata_info=""
446           return 1
447
448 def do_liste(validators):
449     """ 
450        Convertit une arborescence de validateurs en OrVal ou AndVal
451        validators est une liste de validateurs ou de listes ou de tuples
452     """
453     valids=[]
454     for validator in validators:
455         if type(validator) == types.FunctionType:
456            valids.append(FunctionVal(validator))
457         elif type(validator) == types.TupleType:
458            valids.append(OrVal(do_liste(validator)))
459         elif type(validator) == types.ListType:
460            valids.append(AndVal(do_liste(validator)))
461         else:
462            valids.append(validator)
463     return valids
464
465 def validatorFactory(validator):
466     if type(validator) == types.FunctionType:
467        return FunctionVal(validator)
468     elif type(validator) == types.TupleType:
469        return OrVal(do_liste(validator))
470     elif type(validator) == types.ListType:
471        return AndVal(do_liste(validator))
472     else:
473        return validator