]> SALOME platform Git repositories - tools/eficas.git/blob - Noyau/N_VALIDATOR.py
Salome HOME
Modifications liees a MT
[tools/eficas.git] / Noyau / N_VALIDATOR.py
1 # coding=utf-8
2 # Copyright (C) 2007-2017   EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 # ======================================================================
22
23 """
24    Ce module contient toutes les classes necessaires pour
25    implanter le concept de validateur dans Accas
26 """
27 from __future__ import absolute_import
28 from __future__ import print_function
29 try :
30    from builtins import str
31    from builtins import range
32    from builtins import object
33 except : pass
34    
35 import types
36 import traceback
37 import re
38 from .N_ASSD import ASSD
39 from .N_types import isInt, isFloat_or_int, isComplex, isNumber, isStr, isSequence
40 from Extensions.i18n import tr
41 import six
42 from six.moves import range
43
44
45
46 class ValError(Exception):
47     pass
48
49
50 def cls_mro(cls):
51     if hasattr(cls, "__mro__"):
52         return cls.__mro__
53     mro = [cls]
54     for base in cls.__bases__:
55         mro.extend(cls_mro(base))
56     return mro
57
58
59 class Protocol(object):
60
61     def __init__(self, name):
62         self.registry = {}
63         self.name = name
64         self.args = {}
65
66     def register(self, T, A):
67         self.registry[T] = A
68
69     def adapt(self, obj):
70         # (a) verifier si l'objet peut s'adapter au protocole
71         adapt = getattr(obj, '__adapt__', None)
72         if adapt is not None:
73             # on demande à l'objet obj de réaliser lui-meme l'adaptation
74             return adapt(self)
75
76         # (b) verifier si un adapteur est enregistré (si oui l'utiliser)
77         if self.registry:
78             for T in cls_mro(obj.__class__):
79                 if T in self.registry:
80                     return self.registry[T](obj, self, **self.args)
81
82         # (c) utiliser l'adapteur par defaut
83         return self.default(obj, **self.args)
84
85     def default(self, obj, **args):
86         raise TypeError("Can't adapt %s to %s" %
87                         (obj.__class__.__name__, self.name))
88
89
90 class PProtocol(Protocol):
91
92     """Verificateur de protocole paramétré (classe de base)"""
93     # Protocole paramétré. Le registre est unique pour toutes les instances.
94     # La methode register est une methode de classe
95     registry = {}
96
97     def __init__(self, name, **args):
98         self.name = name
99         self.args = args
100
101     def register(cls, T, A):
102         cls.registry[T] = A
103     register = classmethod(register)
104
105
106 class ListProtocol(Protocol):
107
108     """Verificateur de protocole liste : convertit un objet quelconque en liste pour validation ultérieure"""
109
110     def default(self, obj):
111         if type(obj) is tuple:
112             if len(obj) > 0 and obj[0] in ('RI', 'MP'):
113                 # il s'agit d'un complexe ancienne mode. La cardinalite vaut 1
114                 return (obj,)
115             else:
116                 return obj
117         elif type(obj) is list:
118             return obj
119         elif obj == None:
120             # pas de valeur affecte. La cardinalite vaut 0
121             return obj
122         elif isStr(obj):
123             # il s'agit d'une chaine. La cardinalite vaut 1
124             return (obj,)
125         else:
126             try:
127                 # si l'objet supporte len, on a la cardinalite
128                 length = len(obj)
129                 return obj
130             except:
131                 # sinon elle vaut 1
132                 return (obj,)
133
134 listProto = ListProtocol("list")
135
136
137 class TypeProtocol(PProtocol):
138
139     """Verificateur de type parmi une liste de types possibles"""
140     # pas de registre par instance. Registre unique pour toutes les instances
141     # de TypeProtocol
142     registry = {}
143
144     def __init__(self, name, typ=None):
145         PProtocol.__init__(self, name, typ=typ)
146         self.typ = typ
147
148     def default(self, obj, typ):
149
150         err = ""
151         for type_permis in typ:
152             if type_permis == 'R':
153                 if isFloat_or_int(obj):
154                     return obj
155             elif type_permis == 'I':
156                 if isInt(obj):
157                     return obj
158             elif type_permis == 'C':
159                 if self.isComplexe(obj):
160                     return obj
161             elif type_permis == 'TXM':
162                 if isStr(obj): 
163                    return obj
164             elif type_permis == 'shell':
165                 if isStr(obj):
166                     return obj
167             elif type_permis == 'Fichier':
168                 import os
169                 try :
170                    if (len(typ) > 2 and typ[2] == "Sauvegarde") or os.path.isfile(obj):
171                       return obj
172                    else:
173                     raise ValError( "%s n'est pas un fichier valide" % repr(obj))
174                 except : 
175                     raise ValError( "%s n'est pas un fichier valide" % repr(obj))
176
177             elif type_permis == 'FichierNoAbs':
178                 import os
179                 if (len(typ) > 2 and typ[2] == "Sauvegarde") or isinstance(obj, type("")):
180                     return obj
181                 else:
182                     raise ValError( "%s n'est pas un fichier valide" % repr(obj))
183
184             elif type_permis == 'Repertoire':
185                 import os
186                 try : 
187                   if os.path.isdir(obj): return obj
188                   else: raise ValError( "%s n'est pas un repertoire valide" % repr(obj))
189                 except :
190                   raise ValError( "%s n'est pas un repertoire valide" % repr(obj))
191             elif type_permis == 'FichierOuRepertoire':
192                 import os
193                 try : 
194                   if os.path.isdir(obj) or os.path.isfile(obj): return obj
195                   else: raise ValError( "%s n'est pas un fichier ou un repertoire valide" % repr(obj))
196                 except :
197                   raise ValError( "%s n'est pas un fichier ou un repertoire valide" % repr(obj))
198             elif type(type_permis) == type or isinstance(type_permis, type):
199                 try:
200                     if self.isObjectFrom(obj, type_permis):
201                         return obj
202                 except Exception as err:
203                     pass
204             elif  isinstance(type_permis, object):
205                 try:
206                     if type_permis.__convert__(obj):
207                         return obj
208                 except Exception as err:
209                     pass
210             else:
211                 print(("Type non encore gere %s" %type_permis))
212         raise ValError(
213             tr("%s (de type %s) n'est pas d'un type autorise: %s %s") % (repr(obj), type(obj), typ, err))
214
215     def isComplexe(self, valeur):
216         """ Retourne 1 si valeur est un complexe, 0 sinon """
217         if isNumber(valeur):
218             # Pour permettre l'utilisation de complexes Python (accepte les
219             # entiers et réels)
220             return 1
221         elif type(valeur) != tuple:
222             # On n'autorise pas les listes pour les complexes
223             return 0
224         elif len(valeur) != 3:
225             return 0
226         else:
227             # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
228             # valeur suivie de 2 reels.
229             if valeur[0].strip() in ('RI', 'MP'):
230                 try:
231                     v1 = reelProto.adapt(valeur[1]), reelProto.adapt(valeur[2])
232                     return 1
233                 except:
234                     return 0
235             else:
236                 return 0
237
238     def isObjectFrom(self, objet, classe):
239         """
240            Retourne 1 si objet est une instance de la classe classe, 0 sinon
241         """
242         convert = getattr(classe, '__convert__', None)
243         if convert is not None:
244             # classe verifie les valeurs
245             try:
246                 v = convert(objet)
247                 return v is not None
248             except ValueError as err:
249                 raise
250             except:
251                 return 0
252         # On accepte les instances de la classe et des classes derivees
253         return isinstance(objet, classe)
254
255 reelProto = TypeProtocol("reel", typ=('R',))
256
257
258 class CardProtocol(PProtocol):
259
260     """Verificateur de cardinalité """
261     # pas de registre par instance. Registre unique pour toutes les instances
262     registry = {}
263
264     def __init__(self, name, min=1, max=1):
265         PProtocol.__init__(self, name, min=min, max=max)
266
267     def default(self, obj, min, max):
268         length = len(obj)
269         if (length < min) or( length > max):
270             raise ValError(
271                 "Nombre d'arguments de %s incorrect (min = %s, max = %s)" % (repr(obj), min, max))
272         return obj
273
274
275 class IntoProtocol(PProtocol):
276
277     """Verificateur de choix possibles : liste discrète ou intervalle"""
278     # pas de registre par instance. Registre unique pour toutes les instances
279     registry = {}
280
281     def __init__(self, name, into=None, val_min=float('-inf'), val_max=float('inf')):
282      
283         PProtocol.__init__(
284             self, name, into=into, val_min=val_min, val_max=val_max)
285         self.val_min = val_min
286         self.val_max = val_max
287
288     def default(self, obj, into, val_min, val_max):
289         if type(into)  ==types.FunctionType : 
290                maListeDeValeur=into()
291                into=maListeDeValeur
292         if into:
293             if obj not in into:
294                 raise ValError(
295                         tr("La valeur : %s  ne fait pas partie des choix possibles %s") % (repr(obj), into))
296         else:
297             # on est dans le cas d'un ensemble continu de valeurs possibles
298             # (intervalle)
299             if isFloat_or_int(obj):
300                 if val_min == '**':
301                     val_min = obj - 1
302                 if val_max == '**':
303                     val_max = obj + 1
304                 if obj < val_min or obj > val_max:
305                     raise ValError(
306                      tr("La valeur : %s est en dehors du domaine de validite [ %s , %s ]") %(repr(obj), self.val_min, self.val_max))
307         return obj
308
309
310 class MinStr(object):
311     # exemple de classe pour verificateur de type
312     # on utilise des instances de classe comme type (typ=MinStr(3,6), par
313     # exemple)
314
315     def __init__(self, min, max):
316         self.min = min
317         self.max = max
318
319     def __convert__(self, valeur):
320         if isStr(valeur) and self.min <= len(valeur) <= self.max: return valeur
321         raise ValError(
322             "%s n'est pas une chaine de longueur comprise entre %s et %s" % (valeur, self.min, self.max))
323
324     def __repr__(self):
325         return tr("TXM de longueur entre %s et %s" % (self.min, self.max))
326
327
328 class Valid(PProtocol):
329
330     """
331          Cette classe est la classe mere des validateurs Accas
332          Elle doit etre derivee
333          Elle presente la signature des methodes indispensables pour son bon
334          fonctionnement et dans certains cas leur comportement par défaut.
335
336          @ivar cata_info: raison de la validite ou de l'invalidite du validateur meme
337          @type cata_info: C{}
338     """
339     registry = {}
340
341     def __init__(self, **args):
342         PProtocol.__init__(self, "valid", **args)
343
344     def info(self):
345         """
346            Cette methode retourne une chaine de caractères informative sur
347            la validation demandée par le validateur. Elle est utilisée
348            pour produire le compte-rendu de validité du mot clé associé.
349         """
350         return "valeur valide"
351
352     def aide(self):
353         """
354            Cette methode retourne une chaine de caractère qui permet
355            de construire un message d'aide en ligne.
356            En général, le message retourné est le meme que celui retourné par la
357            méthode info.
358         """
359         return self.info()
360
361     def infoErreurItem(self):
362         """
363            Cette méthode permet d'avoir un message d'erreur pour un item
364            dans une liste dans le cas ou le validateur fait des vérifications
365            sur les items d'une liste. Si le validateur fait seulement des
366            vérifications sur la liste elle meme et non sur ses items, la méthode
367            doit retourner une chaine vide.
368         """
369         return " "
370
371     def infoErreurListe(self):
372         """
373            Cette méthode a un comportement complémentaire de celui de
374            infoErreurItem. Elle retourne un message d'erreur lié uniquement
375            aux vérifications sur la liste elle meme et pas sur ses items.
376            Dans le cas où le validateur ne fait pas de vérification sur des
377            listes, elle retourne une chaine vide
378         """
379         return " "
380
381     def verif(self, valeur):
382         """
383             Cette methode sert a verifier si la valeur passee en argument est consideree
384             comme valide ou non par le validateur. Dans le premier cas le validateur retourne 1
385             (valide) sinon 0 (invalide).
386
387             @type valeur: tout type python
388             @param valeur: valeur du mot cle a valider
389             @rtype: C{boolean}
390             @return: indicateur de validite 1 (valide) ou 0 (invalide)
391         """
392         raise NotImplementedError("Must be implemented")
393
394     def verifItem(self, valeur):
395         """
396            La methode verif du validateur effectue une validation complete de
397            la valeur. valeur peut etre un scalaire ou une liste. Le validateur
398            doit traiter les 2 aspects s'il accepte des listes (dans ce cas la
399            methode isList doit retourner 1).
400            La methode valid_item sert pour effectuer des validations partielles
401            de liste. Elle doit uniquement verifier la validite d'un item de
402            liste mais pas les caracteristiques de la liste.
403         """
404         return 0
405
406     def valideListePartielle(self, liste_courante):
407         """
408            Cette methode retourne un entier qui indique si liste_courante est partiellement valide (valeur 1)
409            ou invalide (valeur 0). La validation partielle concerne les listes en cours de construction : on
410            veut savoir si la liste en construction peut etre complétée ou si elle peut déjà etre considérée
411            comme invalide.
412            En général un validateur effectue la meme validation pour les listes partielles et les
413            listes complètes.
414         """
415         return self.verif(liste_courante)
416
417     def verifCata(self):
418         """
419             Cette methode sert a realiser des verifications du validateur lui meme.
420             Elle est facultative et retourne 1 (valide) par defaut.
421             Elle retourne 0 si le validateur est lui meme invalide si par exemple ses
422             parametres de definition ne sont pas corrects.
423             La raison de l'invalidite est stockee dans l'attribut cata_info.
424
425             @rtype: C{boolean}
426             @return: indicateur de validite 1 (valide) ou 0 (invalide)
427         """
428         return 1
429
430     def isList(self):
431         """
432            Cette méthode retourne un entier qui indique si le validateur
433            permet les listes (valeur 1) ou ne les permet pas (valeur 0).
434            Par défaut, un validateur n'autorise que des scalaires.
435         """
436         return 0
437
438     def hasInto(self):
439         """
440            Cette méthode retourne un entier qui indique si le validateur
441            propose une liste de choix (valeur 1) ou n'en propose pas.
442            Par défaut, un validateur n'en propose pas.
443         """
444         return 0
445
446     def getInto(self, liste_courante=None, into_courant=None):
447         """
448            Cette méthode retourne la liste de choix proposée par le validateur.
449            Si le validateur ne propose pas de liste de choix, la méthode
450            retourne None.
451            L'argument d'entrée liste_courante, s'il est différent de None, donne
452            la liste des choix déjà effectués par l'utilisateur. Dans ce cas, la
453            méthode getInto doit calculer la liste des choix en en tenant
454            compte. Par exemple, si le validateur n'autorise pas les répétitions,
455            la liste des choix retournée ne doit pas contenir les choix déjà
456            contenus dans liste_courante.
457            L'argument d'entrée into_courant, s'il est différent de None, donne
458            la liste des choix proposés par d'autres validateurs. Dans ce cas,
459            la méthode getInto doit calculer la liste des choix à retourner
460            en se limitant à cette liste initiale. Par exemple, si into_courant
461            vaut (1,2,3) et que le validateur propose la liste de choix (3,4,5),
462            la méthode ne doit retourner que (3,).
463
464            La méthode getInto peut retourner une liste vide [], ce qui veut
465            dire qu'il n'y a pas (ou plus) de choix possible. Cette situation
466            peut etre normale : l''utilisateur a utilisé tous les choix, ou
467            résulter d'une incohérence des validateurs :
468            choix parmi (1,2,3) ET choix parmi (4,5,6). Il est impossible de
469            faire la différence entre ces deux situations.
470         """
471         return into_courant
472
473
474 class ListVal(Valid):
475
476     """
477         Cette classe sert de classe mère pour tous les validateurs qui acceptent
478         des listes.
479     """
480
481     def isList(self):
482         return 1
483
484     def getInto(self, liste_courante=None, into_courant=None):
485         """
486            Cette méthode getInto effectue un traitement général qui consiste
487            a filtrer la liste de choix into_courant, si elle existe, en ne
488            conservant que les valeurs valides (appel de la méthode valid).
489         """
490         if into_courant is None:
491             return None
492         else:
493             liste_choix = []
494             for e in into_courant:
495                 if self.verif(e):
496                     liste_choix.append(e)
497             return liste_choix
498
499     def convert(self, valeur):
500         """
501            Méthode convert pour les validateurs de listes. Cette méthode
502            fait appel à la méthode convertItem sur chaque élément de la
503            liste.
504         """
505         if isSequence(valeur):
506             for val in valeur:
507                 self.convertItem(val)
508             return valeur
509         else:
510             return self.convertItem(valeur)
511
512     def verif(self, valeur):
513         """
514            Méthode verif pour les validateurs de listes. Cette méthode
515            fait appel à la méthode verifItem sur chaque élément de la
516            liste. Si valeur est un paramètre, on utilise sa valeur effective
517            valeur.valeur.
518         """
519         if isSequence(valeur):
520             for val in valeur:
521                 if not self.verifItem(val):
522                     return 0
523             return 1
524         else:
525             return self.verifItem(valeur)
526
527
528 class Compulsory(ListVal):
529     """
530         Validateur operationnel
531         Verification de la présence obligatoire d'un élément dans une liste
532     """
533     registry = {}
534
535     def __init__(self, elem=()):
536         if not isSequence(elem):
537             elem = (elem,)
538         Valid.__init__(self, elem=elem)
539         self.elem = elem
540         self.cata_info = ""
541
542     def info(self):
543         return (tr(u"valeur %s obligatoire") % self.elem)
544
545     def default(self, valeur, elem):
546         return valeur
547
548     def verifItem(self, valeur):
549         return 1
550
551     def convert(self, valeur):
552         elem = list(self.elem)
553         for val in valeur:
554             v = self.adapt(val)
555             if v in elem:
556                 elem.remove(v)
557         if elem:
558             raise ValError(
559                 tr("%s ne contient pas les elements obligatoires : %s ") % (valeur, elem))
560         return valeur
561
562     def hasInto(self):
563         return 1
564
565     def verif(self, valeur):
566         if not isSequence(valeur):
567             liste = list(valeur)
568         else:
569             liste = valeur
570         for val in self.elem:
571             if val not in liste:
572                 return 0
573         return 1
574
575     def infoErreurItem(self):
576         return tr("La valeur n'est pas dans la liste des choix possibles")
577
578
579 class Together(ListVal):
580     """
581         Validateur operationnel
582         si un des éléments est présent les autres doivent aussi l'être
583     """
584     registry = {}
585
586     def __init__(self, elem=()):
587         if not isSequence(elem):
588             elem = (elem,)
589         Valid.__init__(self, elem=elem)
590         self.elem = elem
591         self.cata_info = ""
592
593     def info(self):
594         return (tr("%s present ensemble") % self.elem)
595
596     def default(self, valeur, elem):
597         return valeur
598
599     def verifItem(self, valeur):
600         return 1
601
602     def convert(self, valeur):
603         elem = list(self.elem)
604         for val in valeur:
605             v = self.adapt(val)
606             if v in elem: elem.remove(v)
607         if ( len(elem) == 0 ): return valeur
608         if len(elem) != len(list(self.elem)) :
609             raise ValError(tr("%s ne contient pas les elements devant etre presents ensemble: %s ") %( valeur, elem))
610         return valeur
611
612     def hasInto(self):
613         return 1
614
615     def verif(self, valeur):
616         if not isSequence(valeur):
617             liste = list(valeur)
618         else:
619             liste = valeur
620         compte = 0
621         for val in self.elem:
622             if val in liste: compte += 1
623         if ( compte == 0 ): return 1
624         if ( compte != len( list(self.elem) ) ): return 0
625         return 1
626
627     def infoErreurItem(self):
628         return tr("La valeur n'est pas dans la liste des choix possibles")
629
630
631 class Absent(ListVal):
632     """
633         Validateur operationnel
634         si un des éléments est présent non valide
635     """
636     registry = {}
637
638     def __init__(self, elem=()):
639         if not isSequence(elem):
640             elem = (elem,)
641         Valid.__init__(self, elem=elem)
642         self.elem = elem
643         self.cata_info = ""
644
645     def info(self):
646         return (tr("%s absent") % self.elem)
647
648     def default(self, valeur, elem):
649         return valeur
650
651     def verifItem(self, valeur):
652         return 1
653
654     def convert(self, valeur):
655         elem = list(self.elem)
656         for val in valeur:
657             v = self.adapt(val)
658             if v in elem:
659                 raise ValError(tr("%s n'est pas autorise : %s ")% (v, elem))
660         return valeur
661
662     def hasInto(self):
663         return 1
664
665     def verif(self, valeur):
666         if not isSequence(valeur):
667             liste = list(valeur)
668         else:
669             liste = valeur
670         for val in self.elem:
671             if val in liste: return 0
672         return 1
673
674     def infoErreurItem(self):
675         return tr("La valeur n'est pas dans la liste des choix possibles")
676
677
678 class NoRepeat(ListVal):
679     """
680         Validateur operationnel
681         Verification d'absence de doublons dans la liste.
682     """
683     def __init__(self):
684         Valid.__init__(self)
685         self.cata_info = ""
686
687     def info(self):
688         return tr("Pas de doublon dans la liste")
689
690     def infoErreurListe(self):
691         return tr("Les doublons ne sont pas permis")
692
693     def default(self, valeur):
694         if valeur in self.liste:
695             raise ValError( tr("%s est un doublon") % valeur)
696         return valeur
697
698     def convert(self, valeur):
699         self.liste = []
700         for val in valeur:
701             v = self.adapt(val)
702             self.liste.append(v)
703         return valeur
704
705     def verifItem(self, valeur):
706         return 1
707
708     def verif(self, valeur):
709         if isSequence(valeur):
710             liste = list(valeur)
711             for val in liste:
712                 if liste.count(val) != 1:
713                     return 0
714             return 1
715         else:
716             return 1
717
718     def getInto(self, liste_courante=None, into_courant=None):
719         """
720         Methode getInto spécifique pour validateur NoRepeat, on retourne
721         une liste de choix qui ne contient aucune valeur de into_courant
722         déjà contenue dans liste_courante
723         """
724         if into_courant is None:
725             liste_choix = None
726         else:
727             liste_choix = []
728             for e in into_courant:
729                 if e in liste_choix:
730                     continue
731                 if liste_courante is not None and e in liste_courante:
732                     continue
733                 liste_choix.append(e)
734         return liste_choix
735
736
737 class LongStr(ListVal):
738
739     """
740         Validateur operationnel
741         Verification de la longueur d une chaine
742     """
743
744     def __init__(self, low, high):
745         ListVal.__init__(self, low=low, high=high)
746         self.low = low
747         self.high = high
748         self.cata_info = ""
749
750     def info(self):
751         return (tr("longueur de la chaine entre %s et %s") %( self.low, self.high))
752
753     def infoErreurItem(self):
754         return tr("Longueur de la chaine incorrecte")
755
756     def convert(self, valeur):
757         for val in valeur:
758             v = self.adapt(val)
759         return valeur
760
761     def verifItem(self, valeur):
762         try:
763             self.adapt(valeur)
764             return 1
765         except:
766             return 0
767
768     def default(self, valeur, low, high):
769         if not isStr(valeur):
770             raise ValError ("%s n'est pas une chaine" % repr(valeur))
771         if valeur[0] == "'" and valeur[-1] == "'":
772             low = low + 2
773             high = high + 2
774         if len(valeur) < low or len(valeur) > high:
775             raise ValError(
776                 "%s n'est pas de la bonne longueur" % repr(valeur))
777         return valeur
778
779
780 class OnlyStr(ListVal):
781
782     """
783         Validateur operationnel
784         Valide que c'est une chaine
785     """
786
787     def __init__(self):
788         ListVal.__init__(self)
789         self.cata_info = ""
790
791     def info(self):
792         return tr("regarde si c'est une chaine")
793
794     def infoErreurItem(self):
795         return tr("Ce n'est pas une chaine")
796
797     def convert(self, valeur):
798         for val in valeur:
799             v = self.adapt(val)
800         return valeur
801
802     def verifItem(self, valeur):
803         try:
804             self.adapt(valeur)
805             return 1
806         except:
807             return 0
808
809     def default(self, valeur):
810         if not isStr(valeur):
811             raise ValError (tr("%s n'est pas une chaine") % repr(valeur))
812         return valeur
813
814
815 class OrdList(ListVal):
816
817     """
818         Validateur operationnel
819         Verification qu'une liste est croissante ou decroissante
820     """
821
822     def __init__(self, ord):
823         ListVal.__init__(self, ord=ord)
824         self.ord = ord
825         self.cata_info = ""
826
827     def info(self):
828         return ("liste %s" % self.ord)
829
830     def infoErreurListe(self):
831         return (tr("La liste doit etre en ordre %s") % self.ord)
832
833     def convert(self, valeur):
834         self.val = None
835         self.liste = valeur
836         for v in valeur:
837             self.adapt(v)
838         return valeur
839
840     def default(self, valeur, ord):
841         if self.ord == 'croissant':
842             if self.val is not None and valeur < self.val:
843                 raise ValError(
844                     (tr("%s n'est pas par valeurs croissantes") % repr(self.liste)))
845         elif self.ord == 'decroissant':
846             if self.val is not None and valeur > self.val:
847                 raise ValError(
848                     (tr("%s n'est pas par valeurs decroissantes") % repr(self.liste)))
849         self.val = valeur
850         return valeur
851
852     def verifItem(self, valeur):
853         return 1
854
855     def getInto(self, liste_courante=None, into_courant=None):
856         """
857         Methode getInto spécifique pour validateur OrdList, on retourne
858         une liste de choix qui ne contient aucune valeur de into_courant
859         dont la valeur est inférieure à la dernière valeur de
860         liste_courante, si elle est différente de None.
861         """
862         if into_courant is None:
863             return None
864         elif not liste_courante:
865             return into_courant
866         else:
867             liste_choix = []
868             last_val = liste_choix[-1]
869             for e in into_courant:
870                 if self.ord == 'croissant' and e <= last_val:
871                     continue
872                 if self.ord == 'decroissant' and e >= last_val:
873                     continue
874                 liste_choix.append(e)
875             return liste_choix
876
877
878 class OrVal(Valid):
879
880     """
881         Validateur operationnel
882         Cette classe est un validateur qui controle une liste de validateurs
883         Elle verifie qu'au moins un des validateurs de la liste valide la valeur
884     """
885
886     def __init__(self, validators=()):
887         if not isSequence(validators):
888             validators = (validators,)
889         self.validators = []
890         for validator in validators:
891             if type(validator) == types.FunctionType:
892                 self.validators.append(FunctionVal(validator))
893             else:
894                 self.validators.append(validator)
895         self.cata_info = ""
896
897     def info(self):
898         return "\n ou ".join([v.info() for v in self.validators])
899
900     def convert(self, valeur):
901         for validator in self.validators:
902             try:
903                 return validator.convert(valeur)
904             except:
905                 pass
906         raise ValError(tr("%s n'est pas du bon type")% repr(valeur))
907
908     def infoErreurItem(self):
909         l = []
910         for v in self.validators:
911             err = v.infoErreurItem()
912             if err != " ":
913                 l.append(err)
914         chaine = " \n ou ".join(l)
915         return chaine
916
917     def infoErreurListe(self):
918         l = []
919         for v in self.validators:
920             err = v.infoErreurListe()
921             if err != " ":
922                 l.append(err)
923         chaine = " \n ou ".join(l)
924         return chaine
925
926     def isList(self):
927         """
928            Si plusieurs validateurs sont reliés par un OU
929            il suffit qu'un seul des validateurs attende une liste
930            pour qu'on considère que leur union attend une liste.
931         """
932         for validator in self.validators:
933             v = validator.isList()
934             if v:
935                 return 1
936         return 0
937
938     def verif(self, valeur):
939         for validator in self.validators:
940             v = validator.verif(valeur)
941             if v:
942                 return 1
943         return 0
944
945     def verifItem(self, valeur):
946         for validator in self.validators:
947             v = validator.verifItem(valeur)
948             if v:
949                 return 1
950         return 0
951
952     def verifCata(self):
953         infos = []
954         for validator in self.validators:
955             v = validator.verifCata()
956             if not v:
957                 infos.append(validator.cata_info)
958         if infos:
959             self.cata_info = "\n".join(infos)
960             return 0
961         self.cata_info = ""
962         return 1
963
964     def hasInto(self):
965         """
966         Dans le cas ou plusieurs validateurs sont reliés par un OU
967         il faut que tous les validateurs proposent un choix pour
968         qu'on considère que leur union propose un choix.
969         Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
970         En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un choix (1,2,3,4,5,6)
971         """
972         for validator in self.validators:
973             v = validator.hasInto()
974             if not v:
975                 return 0
976         return 1
977
978     def getInto(self, liste_courante=None, into_courant=None):
979         """
980         Dans le cas ou plusieurs validateurs sont reliés par un OU
981         tous les validateurs doivent proposer un choix pour
982         qu'on considère que leur union propose un choix. Tous les choix
983         proposés par les validateurs sont réunis (opérateur d'union).
984         Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
985         En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un
986         choix (1,2,3,4,5,6)
987         """
988         validator_into = []
989         for validator in self.validators:
990             v_into = validator.getInto(liste_courante, into_courant)
991             if v_into is None:
992                 return v_into
993             validator_into.extend(v_into)
994         return validator_into
995
996     def valideListePartielle(self, liste_courante=None):
997         """
998          Méthode de validation de liste partielle pour le validateur Or.
999          Si un des validateurs gérés par le validateur Or considère la
1000          liste comme valide, le validateur Or la considère comme valide.
1001         """
1002         for validator in self.validators:
1003             v = validator.valideListePartielle(liste_courante)
1004             if v:
1005                 return 1
1006         return 0
1007
1008
1009 class AndVal(Valid):
1010
1011     """
1012         Validateur operationnel
1013         Cette classe est un validateur qui controle une liste de validateurs
1014         Elle verifie que tous les validateurs de la liste valident la valeur
1015     """
1016
1017     def __init__(self, validators=()):
1018         if not isSequence(validators):
1019             validators = (validators,)
1020         self.validators = []
1021         for validator in validators:
1022             if type(validator) == types.FunctionType:
1023                 self.validators.append(FunctionVal(validator))
1024             else:
1025                 self.validators.append(validator)
1026             if hasattr(validator, 'fonctions'):
1027                 for fonction in validator.fonctions:
1028                     f = getattr(validator, fonction)
1029                     setattr(self, fonction, f)
1030         self.cata_info = ""
1031
1032     def info(self):
1033         return "\n et ".join([v.info() for v in self.validators])
1034
1035     def convert(self, valeur):
1036         for validator in self.validators:
1037             valeur = validator.convert(valeur)
1038         return valeur
1039
1040     def infoErreurItem(self):
1041         chaine = ""
1042         a = 1
1043         for v in self.validators:
1044             if v.infoErreurItem() != " ":
1045                 if a == 1:
1046                     chaine = v.infoErreurItem()
1047                     a = 0
1048                 else:
1049                     chaine = chaine + " \n et " + v.infoErreurItem()
1050         return chaine
1051
1052     def infoErreurListe(self):
1053         chaine=""
1054         a = 1
1055         for v in self.validators:
1056             if v.infoErreurListe() != " ":
1057                 if a == 1:
1058                     chaine = v.infoErreurListe()
1059                     a = 0
1060                 else:
1061                     chaine = chaine + " \n et " + v.infoErreurListe()
1062         return chaine
1063
1064     def verif(self, valeur):
1065         for validator in self.validators:
1066             v = validator.verif(valeur)
1067             if not v:
1068                 self.local_info = validator.info()
1069                 return 0
1070         return 1
1071
1072     def verifItem(self, valeur):
1073         for validator in self.validators:
1074             v = validator.verifItem(valeur)
1075             if not v:
1076                 # L'info n'est probablement pas la meme que pour verif ???
1077                 self.local_info = validator.info()
1078                 return 0
1079         return 1
1080
1081     def verifCata(self):
1082         infos = []
1083         for validator in self.validators:
1084             v = validator.verifCata()
1085             if not v:
1086                 infos.append(validator.cata_info)
1087         if infos:
1088             self.cata_info = "\n".join(infos)
1089             return 0
1090         self.cata_info = ""
1091         return 1
1092
1093     def valideListePartielle(self, liste_courante=None):
1094         """
1095          Méthode de validation de liste partielle pour le validateur And.
1096          Tous les validateurs gérés par le validateur And doivent considérer
1097          la liste comme valide, pour que le validateur And la considère
1098          comme valide.
1099         """
1100         for validator in self.validators:
1101             v = validator.valideListePartielle(liste_courante)
1102             if not v:
1103                 return 0
1104         return 1
1105
1106     def isList(self):
1107         """
1108         Si plusieurs validateurs sont reliés par un ET
1109         il faut que tous les validateurs attendent une liste
1110         pour qu'on considère que leur intersection attende une liste.
1111         Exemple Range(2,5) ET Card(1) n'attend pas une liste
1112         Range(2,5) ET Pair attend une liste
1113         """
1114         for validator in self.validators:
1115             v = validator.isList()
1116             if v == 0:
1117                 return 0
1118         return 1
1119
1120     def hasInto(self):
1121         """
1122         Dans le cas ou plusieurs validateurs sont reliés par un ET
1123         il suffit qu'un seul validateur propose un choix pour
1124         qu'on considère que leur intersection propose un choix.
1125         Exemple : Enum(1,2,3) ET entier pair, propose un choix
1126         En revanche, entier pair ET superieur à 10 ne propose pas de choix
1127         """
1128         for validator in self.validators:
1129             v = validator.hasInto()
1130             if v:
1131                 return 1
1132         return 0
1133
1134     def getInto(self, liste_courante=None, into_courant=None):
1135         """
1136         Dans le cas ou plusieurs validateurs sont reliés par un ET
1137         il suffit qu'un seul validateur propose un choix pour
1138         qu'on considère que leur intersection propose un choix. Tous les
1139         choix proposés par les validateurs sont croisés (opérateur
1140         d'intersection)
1141         Exemple : Enum(1,2,3) ET entier pair, propose un choix (2,)
1142         En revanche, Enum(1,2,3) ET Enum(4,5,6) ne propose pas de choix.
1143         """
1144         for validator in self.validators:
1145             into_courant = validator.getInto(liste_courante, into_courant)
1146             if into_courant in ([], None):
1147                 break
1148         return into_courant
1149
1150
1151 def do_liste(validators):
1152     """
1153        Convertit une arborescence de validateurs en OrVal ou AndVal
1154        validators est une liste de validateurs ou de listes ou de tuples
1155     """
1156     valids = []
1157     for validator in validators:
1158         if type(validator) == types.FunctionType:
1159             valids.append(FunctionVal(validator))
1160         elif type(validator) is tuple:
1161             valids.append(OrVal(do_liste(validator)))
1162         elif type(validator) is list:
1163             valids.append(AndVal(do_liste(validator)))
1164         else:
1165             valids.append(validator)
1166     return valids
1167
1168
1169 def validatorFactory(validator):
1170     if type(validator) == types.FunctionType:
1171         return FunctionVal(validator)
1172     elif type(validator) is tuple:
1173         return OrVal(do_liste(validator))
1174     elif type(validator) is list:
1175         return AndVal(do_liste(validator))
1176     else:
1177         return validator
1178
1179 # Ci-dessous : exemples de validateur (peu testés)
1180
1181
1182 class RangeVal(ListVal):
1183
1184     """
1185         Exemple de classe validateur : verification qu'une valeur
1186         est dans un intervalle.
1187         Pour une liste on verifie que tous les elements sont
1188         dans l'intervalle
1189         Susceptible de remplacer les attributs "vale_min" "vale_max"
1190         dans les catalogues
1191     """
1192
1193     def __init__(self, low, high):
1194         self.low = low
1195         self.high = high
1196         self.cata_info = (tr("%s doit etre inferieur a %s") % (low, high))
1197
1198     def info(self):
1199         return (tr("valeur dans l'intervalle %s , %s") %( self.low, self.high))
1200
1201     def convertItem(self, valeur):
1202         if valeur > self.low and valeur < self.high:
1203             return valeur
1204         raise ValError(tr("%s devrait etre comprise entre %s et %s") % (valeur, self.low, self.high))
1205
1206     def verifItem(self, valeur):
1207         return valeur > self.low and valeur < self.high
1208
1209     def infoErreurItem(self):
1210         return (tr("la valeur %s doit etre comprise entre %s et %s") % (valeur, self.low, self.high))
1211
1212
1213     def verifCata(self):
1214         if self.low > self.high:
1215             return 0
1216         return 1
1217
1218
1219 class CardVal(Valid):
1220
1221     """
1222         Exemple de classe validateur : verification qu'une liste est
1223         d'une longueur superieur a un minimum (min) et inferieure
1224         a un maximum (max).
1225         Susceptible de remplacer les attributs "min" "max" dans les
1226         catalogues
1227     """
1228
1229     def __init__(self, min=float('-inf'), max=float('inf')):
1230         self.min = min
1231         self.max = max
1232         self.cata_info = (tr("%s doit etre inferieur a %s") %(min, max))
1233
1234     def info(self):
1235         return (tr("longueur de liste comprise entre  %s et %s") %(self.min, self.max))
1236
1237     def infoErreurListe(self):
1238         return (tr("Le cardinal de la liste doit etre compris entre %s et %s") % (self.min, self.max))
1239
1240     def isList(self):
1241         return self.max == '**' or self.max > 1
1242
1243     def getInto(self, liste_courante=None, into_courant=None):
1244         if into_courant is None:
1245             return None
1246         elif liste_courante is None:
1247             return into_courant
1248         elif self.max == '**':
1249             return into_courant
1250         elif len(liste_courante) < self.max:
1251             return into_courant
1252         else:
1253             return []
1254
1255     def convert(self, valeur):
1256         if isSequence(valeur):
1257             l = len(valeur)
1258         elif valeur is None:
1259             l = 0
1260         else:
1261             l = 1
1262         if self.max != '**' and l > self.max:
1263             raise ValError(
1264                 tr("%s devrait etre de longueur inferieure a %s") % (valeur, self.max))
1265         if self.min != '**' and l < self.min:
1266             raise ValError(
1267                 tr("%s devrait etre de longueur superieure a %s") % (valeur, self.min))
1268         return valeur
1269
1270     def verifItem(self, valeur):
1271         return 1
1272
1273     def verif(self, valeur):
1274         if isSequence(valeur):
1275             if self.max != '**' and len(valeur) > self.max:
1276                 return 0
1277             if self.min != '**' and len(valeur) < self.min:
1278                 return 0
1279             return 1
1280         else:
1281             if self.max != '**' and 1 > self.max:
1282                 return 0
1283             if self.min != '**' and 1 < self.min:
1284                 return 0
1285             return 1
1286
1287     def verifCata(self):
1288         if self.min != '**' and self.max != '**' and self.min > self.max:
1289             return 0
1290         return 1
1291
1292     def valideListePartielle(self, liste_courante=None):
1293         validite = 1
1294         if liste_courante != None:
1295             if len(liste_courante) > self.max:
1296                 validite = 0
1297         return validite
1298
1299
1300 class PairVal(ListVal):
1301
1302     """
1303         Exemple de classe validateur : verification qu'une valeur
1304         est paire.
1305         Pour une liste on verifie que tous les elements sont
1306         pairs
1307     """
1308
1309     def __init__(self):
1310         ListVal.__init__(self)
1311         self.cata_info = ""
1312
1313     def info(self):
1314         return _(u"valeur paire")
1315
1316     def infoErreurItem(self):
1317         return tr("La valeur saisie doit etre paire")
1318
1319     def convert(self, valeur):
1320         for val in valeur:
1321             v = self.adapt(val)
1322             if v % 2 != 0:
1323                 raise ValError(
1324                     tr("%s contient des valeurs non paires") % repr(valeur))
1325         return valeur
1326
1327     def default(self, valeur):
1328         return valeur
1329
1330     def verifItem(self, valeur):
1331         if type(valeur) not in six.integer_types:
1332             return 0
1333         return valeur % 2 == 0
1334
1335     def verif(self, valeur):
1336         if isSequence(valeur):
1337             for val in valeur:
1338                 if val % 2 != 0:
1339                     return 0
1340             return 1
1341         else:
1342             if valeur % 2 != 0:
1343                 return 0
1344             return 1
1345
1346
1347 class EnumVal(ListVal):
1348
1349     """
1350         Exemple de classe validateur : verification qu'une valeur
1351         est prise dans une liste de valeurs.
1352         Susceptible de remplacer l attribut "into" dans les catalogues
1353     """
1354
1355     def __init__(self, into=()):
1356         if not isSequence(into):
1357             into = (into,)
1358         self.into = into
1359         self.cata_info = ""
1360
1361     def info(self):
1362         return ("valeur dans %s" % self.into)
1363
1364     def convertItem(self, valeur):
1365         if valeur in self.into:
1366             return valeur
1367         raise ValError(
1368             tr("%s contient des valeurs hors des choix possibles: %s ") % (valeur, self.into))
1369
1370     def verifItem(self, valeur):
1371         if valeur not in self.into:
1372             return 0
1373         return 1
1374
1375     def hasInto(self):
1376         return 1
1377
1378     def getInto(self, liste_courante=None, into_courant=None):
1379         if into_courant is None:
1380             liste_choix = list(self.into)
1381         else:
1382             liste_choix = []
1383             for e in into_courant:
1384                 if e in self.into:
1385                     liste_choix.append(e)
1386         return liste_choix
1387
1388     def infoErreurItem(self):
1389         return tr("La valeur n'est pas dans la liste des choix possibles")
1390
1391
1392 def ImpairVal(valeur):
1393     """
1394           Exemple de validateur
1395         Cette fonction est un validateur. Elle verifie que la valeur passee
1396         est bien un nombre impair.
1397     """
1398     if isSequence(valeur):
1399         for val in valeur:
1400             if val % 2 != 1:
1401                 return 0
1402         return 1
1403     else:
1404         if valeur % 2 != 1:
1405             return 0
1406         return 1
1407
1408 ImpairVal.info = "valeur impaire"
1409
1410
1411 class F1Val(Valid):
1412
1413     """
1414         Exemple de validateur
1415         Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie
1416         que la somme des cles A et B vaut une valeur donnee
1417         en parametre du validateur
1418     """
1419
1420     def __init__(self, somme=10):
1421         self.somme = somme
1422         self.cata_info = ""
1423
1424     def info(self):
1425         return (tr("valeur %s pour la somme des cles A et B ") % self.somme)
1426
1427     def verif(self, valeur):
1428         if isSequence(valeur):
1429             for val in valeur:
1430                 if not "A" in val:
1431                     return 0
1432                 if not "B" in val:
1433                     return 0
1434                 if val["A"] + val["B"] != self.somme:
1435                     return 0
1436             return 1
1437         else:
1438             if not "A" in valeur:
1439                 return 0
1440             if not "B" in valeur:
1441                 return 0
1442             if valeur["A"] + valeur["B"] != self.somme:
1443                 return 0
1444             return 1
1445
1446
1447 class FunctionVal(Valid):
1448
1449     """
1450         Exemple de validateur
1451         Cette classe est un validateur qui est initialise avec une fonction
1452     """
1453
1454     def __init__(self, function):
1455         self.function = function
1456
1457     def info(self):
1458         return self.function.info
1459
1460     def infoErreurItem(self):
1461         return self.function.info
1462
1463     def verif(self, valeur):
1464         return self.function(valeur)
1465
1466     def verifItem(self, valeur):
1467         return self.function(valeur)
1468
1469     def convert(self, valeur):
1470         return valeur
1471
1472 # MC ca ne devrait plus servir !
1473 CoercableFuncs = {int:     int,
1474                   int:    int,
1475                   float:   float,
1476                   complex: complex,
1477                   str: six.text_type}
1478
1479
1480 #class FunctionValObjet(FunctionVal):
1481 #OOOOOOOOOOOOOOo
1482
1483 class TypeVal(ListVal):
1484
1485     """
1486         Exemple de validateur
1487         Cette classe est un validateur qui controle qu'une valeur
1488         est bien du type Python attendu.
1489         Pour une liste on verifie que tous les elements sont du bon type.
1490         Semblable a InstanceVal mais ici on fait le test par tentative de conversion
1491         alors qu'avec InstanceVal on ne teste que si isinstance est vrai.
1492     """
1493
1494     def __init__(self, aType):
1495         # Si aType n'est pas un type, on le retrouve a l'aide de la fonction type
1496         # type(1) == int;type(0.2)==float;etc.
1497         if type(aType) != type:
1498             aType = type(aType)
1499         self.aType = aType
1500         try:
1501             self.coerce = CoercableFuncs[aType]
1502         except:
1503             self.coerce = self.identity
1504
1505     def info(self):
1506         return (tr("valeur de %s") % self.aType)
1507
1508     def identity(self, value):
1509         if type(value) == self.aType:
1510             return value
1511         raise ValError
1512
1513     def convertItem(self, valeur):
1514         return self.coerce(valeur)
1515
1516     def verifItem(self, valeur):
1517         try:
1518             self.coerce(valeur)
1519         except:
1520             return 0
1521         return 1
1522
1523
1524 class InstanceVal(ListVal):
1525
1526     """
1527         Exemple de validateur
1528         Cette classe est un validateur qui controle qu'une valeur est
1529         bien une instance (au sens Python) d'une classe
1530         Pour une liste on verifie chaque element de la liste
1531     """
1532
1533     def __init__(self, aClass):
1534         # Si aClass est une classe on la memorise dans self.aClass
1535         # sinon c'est une instance dont on memorise la classe
1536         #if type(aClass) == types.InstanceType:
1537         if type(aClass) == object :
1538             # instance ancienne mode
1539             aClass = aClass.__class__
1540         elif type(aClass) == type:
1541             # classe ancienne mode
1542             aClass = aClass
1543         elif type(aClass) == type:
1544             # classe nouvelle mode
1545             aClass = aClass
1546         elif isinstance(aClass, object):
1547             # instance nouvelle mode
1548             aClass = type(aClass)
1549         else:
1550             raise ValError(tr("type non supporté"))
1551
1552         self.aClass = aClass
1553
1554     def info(self):
1555         return (tr("valeur d'instance de %s") % self.aClass.__name__)
1556
1557     def verifItem(self, valeur):
1558         if not isinstance(valeur, self.aClass):
1559             return 0
1560         return 1
1561
1562
1563 class VerifTypeTuple(ListVal):
1564
1565     def __init__(self, typeDesTuples):
1566         self.typeDesTuples = typeDesTuples
1567         Valid.__init__(self)
1568         self.cata_info = ""
1569
1570     def info(self):
1571         return tr(": verifie les \ntypes dans un tuple")
1572
1573     def infoErreurListe(self):
1574         return tr("Les types entres ne sont pas permis")
1575
1576     def default(self, valeur):
1577         return valeur
1578
1579     def isList(self):
1580         return 1
1581
1582     def convertItem(self, valeur):
1583         if len(valeur) != len(self.typeDesTuples):
1584             raise ValError(
1585                 tr("%s devrait etre de type  %s ") %( valeur, self.typeDesTuples))
1586         for i in range(len(valeur)):
1587             ok = self.verifType(valeur[i], self.typeDesTuples[i])
1588             if ok != 1:
1589                 raise ValError(
1590                     tr("%s devrait etre de type  %s ") % (valeur, self.typeDesTuples))
1591         return valeur
1592
1593     def verifItem(self, valeur):
1594         try:
1595             if len(valeur) != len(self.typeDesTuples):
1596                 return 0
1597             for i in range(len(valeur)):
1598                 ok = self.verifType(valeur[i], self.typeDesTuples[i])
1599                 if ok != 1:
1600                     return 0
1601         except:
1602             return 0
1603         return 1
1604
1605     def verifType(self, valeur, type_permis):
1606         if type_permis == 'R':
1607             if type(valeur) in (int, float, int):
1608                 return 1
1609         elif type_permis == 'I':
1610             if type(valeur) in (int, int):
1611                 return 1
1612         elif type_permis == 'C':
1613             if self.isComplexe(valeur):
1614                 return 1
1615         elif type_permis == 'TXM':
1616             if type(valeur) == bytes or type(valeur) == str:
1617                 return 1
1618         elif isinstance(valeur, type_permis):
1619                 return 1
1620         return 0
1621
1622     def verif(self, valeur):
1623         if type(valeur) in (list, tuple):
1624             liste = list(valeur)
1625             for val in liste:
1626                 if self.verifItem(val) != 1:
1627                     return 0
1628             return 1
1629
1630
1631 class VerifExiste(ListVal):
1632
1633     """
1634        fonctionne avec into
1635        Met une liste à jour selon les mot clefs existant
1636        exemple si into = ("A","B","C")
1637        si au niveau N du JDC les objets "A" et "C" existe
1638        alors la liste des into deviendra ( "A","C")
1639
1640        niveauVerif est le niveau du JDC dans lequel va s effectuer la verification
1641        niveauVerif est defini par rapport au Noeud :
1642        exemple niveauVerif = 1 : on verifie les freres
1643                niveauVerif = 2 : on verifie les oncles..
1644     """
1645
1646     def __init__(self, niveauVerif):
1647         ListVal.__init__(self)
1648         self.niveauVerif = niveauVerif
1649         self.MCSimp = None
1650         self.listeDesFreres = ()
1651         self.fonctions = ('verifieListe', 'set_MCSimp')
1652
1653     def isList(self):
1654         return 1
1655
1656     def verifieListe(self, liste):
1657         self.set_MCSimp(self.MCSimp)
1658         for item in liste:
1659             if not(item in self.listeDesFreres):
1660                 return 0
1661         return 1
1662
1663     def verifItem(self, valeur):
1664         self.set_MCSimp(self.MCSimp)
1665         if valeur in self.listeDesFreres:
1666             return 1
1667         return 0
1668
1669     def set_MCSimp(self, MCSimp):
1670         self.MCSimp = MCSimp
1671         k = self.niveauVerif
1672         mc = MCSimp
1673         while (k != 0):
1674             parent = mc.parent
1675             mc = parent
1676             k = k - 1
1677         # on met la liste à jour
1678         parent.forceRecalcul = self.niveauVerif
1679         self.listeDesFreres = parent.listeMcPresents()
1680
1681     def convertItem(self, valeur):
1682         if valeur in self.listeDesFreres:
1683             return valeur
1684         raise ValError(
1685             tr("%s n'est pas dans %s") % (valeur, self.listeDesFreres))
1686
1687
1688 class RegExpVal(ListVal):
1689
1690     """
1691     Vérifie qu'une chaîne de caractère corresponde à l'expression régulière 'pattern'
1692     """
1693
1694     errormsg = 'La chaîne "%(value)s" ne correspond pas au motif "%(pattern)s"'
1695
1696     def __init__(self, pattern):
1697         self.pattern = pattern
1698         self.compiled_regexp = re.compile(pattern)
1699
1700     def info(self):
1701         return tr('Une chaîne correspondant au motif ') + str(self.pattern) + tr(" est attendue")
1702
1703     def infoErreurItem(self):
1704         return tr('Une chaîne correspondant au motif ') + str(self.pattern) + tr(" est attendue")
1705
1706     def verifItem(self, valeur):
1707         if self.compiled_regexp.match(valeur):
1708             return 1
1709         else:
1710             return (0, self.errormsg % {"value": valeur, "pattern": self.pattern})
1711
1712     def convertItem(self, valeur):
1713         if self.compiled_regexp.match(valeur):
1714             return valeur
1715         else:
1716             raise ValError(self.errormsg %
1717                            {"value": valeur, "pattern": self.pattern})
1718
1719
1720 class FileExtVal(RegExpVal):
1721
1722     """
1723     Vérifie qu'une chaîne de caractère soit un nom de fichier valide avec l'extension 'ext'
1724     """
1725
1726     def __init__(self, ext):
1727         self.ext = ext
1728         self.errormsg = '"%%(value)s" n\'est pas un nom de fichier %(ext)s valide' % {
1729             "ext": ext}
1730         #PNPN Modif pour Adao
1731         RegExpVal.__init__(self, "^\S+\.%s$" % self.ext)
1732
1733
1734     def info(self):
1735         return ('Un nom de fichier se terminant par ".%s" est attendu.' % self.ext)
1736
1737     def infoErreurItem(self):
1738         return ('Un nom de fichier se terminant par ".%s" est attendu.' % self.ext)
1739
1740 class CreeMotClef(object):
1741     def __init__(self,MotClef ):
1742         self.MotClef=MotClef
1743         self.MCSimp=None
1744          
1745     def convert(self, lval):
1746         try : valeur=lval[0]
1747         except  : return lval
1748
1749         parent= self.MCSimp.parent
1750         if hasattr(parent, 'inhibeValidator') and parent.inhibeValidator: return lval
1751
1752
1753         if parent.getChild(self.MotClef) == None : longueur=0
1754         else : longueur=len(parent.getChild(self.MotClef))
1755
1756         pos=parent.getIndexChild(self.MCSimp.nom)+1
1757         while longueur < valeur : 
1758            parent.inhibeValidator=1
1759            parent.addEntite(self.MotClef,pos)
1760            pos=pos+1
1761            parent.inhibeValidator=0
1762            longueur=len(parent.getChild(self.MotClef))
1763
1764         if longueur > valeur : 
1765            parent.inhibeValide=1
1766            parentObj=parent.getChild(self.MotClef)
1767            obj=parent.getChild(self.MotClef)[-1]
1768            parentObj.suppEntite(obj)
1769            longueur=len(parent.getChild(self.MotClef))
1770            parent.inhibeValide=0
1771         return lval
1772
1773     def info(self):
1774         return "Cree le bon nombre de Mot %s"  % self.MotClef
1775
1776     def verifItem(self, valeur):
1777         return 1
1778
1779     def set_MCSimp(self, MCSimp):
1780         #print "dans set_MCSimp"
1781         self.MCSimp=MCSimp