X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=Noyau%2FN_VALIDATOR.py;h=88ecd075f1203482ec0cf815fc1e7b62de8161de;hb=aaf54e27d39904aa7b9a56498e9f08f3e71351f7;hp=1fcbe331df9fefc0e41c7891f83be1f191b997ca;hpb=be2b4b6b27757f76577d822096192710f80bdf7b;p=tools%2Feficas.git diff --git a/Noyau/N_VALIDATOR.py b/Noyau/N_VALIDATOR.py index 1fcbe331..88ecd075 100644 --- a/Noyau/N_VALIDATOR.py +++ b/Noyau/N_VALIDATOR.py @@ -1,473 +1,1780 @@ -#@ MODIF N_VALIDATOR Noyau DATE 09/09/2003 AUTEUR DURAND C.DURAND -# CONFIGURATION MANAGEMENT OF EDF VERSION -# ====================================================================== -# COPYRIGHT (C) 1991 - 2003 EDF R&D WWW.CODE-ASTER.ORG -# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY -# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. -# -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. -# -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. +# coding=utf-8 +# Copyright (C) 2007-2015 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + # ====================================================================== + """ Ce module contient toutes les classes necessaires pour implanter le concept de validateur dans Accas """ -import types,exceptions - -class ValError ( exceptions.Exception ): - pass - -class Valid: - """ - Cette classe est la classe mere des validateurs Accas - Elle doit etre derivee - Elle ne presente que la signature des methodes - indispensables pour son bon fonctionnement - - @ivar cata_info: raison de la validite ou de l'invalidite du validateur meme - @type cata_info: C{string} - """ - def __init__(self,*tup,**args): - """ - Cette methode sert a initialiser les attributs du validateur - """ - self.cata_info="" - raise "Must be implemented" - - def info(self): - return "valeur valide" - - def verif(self,valeur): - """ - Cette methode sert a verifier si la valeur passee en argument est consideree - comme valide ou non par le validateur. Dans le premier cas le validateur retourne 1 - (valide) sinon 0 (invalide). - - @type valeur: tout type python - @param valeur: valeur du mot cle a valider - @rtype: C{boolean} - @return: indicateur de validite 1 (valide) ou 0 (invalide) - """ - raise "Must be implemented" +from __future__ import absolute_import +from __future__ import print_function +try : + from builtins import str + from builtins import range + from builtins import object +except : pass - def error(self,valeur): - return 0 - - def verif_cata(self): - """ - Cette methode sert a realiser des verifications du validateur lui meme. - Elle est facultative et retourne 1 (valide) par defaut. - Elle retourne 0 si le validateur est lui meme invalide si par exemple ses - parametres de definition ne sont pas corrects. - La raison de l'invalidite est stockee dans l'attribut cata_info. - - @rtype: C{boolean} - @return: indicateur de validite 1 (valide) ou 0 (invalide) - """ - return 1 - -class RangeVal(Valid): - """ - Exemple de classe validateur : verification qu'une valeur - est dans un intervalle. - Pour une liste on verifie que tous les elements sont - dans l'intervalle - Susceptible de remplacer les attributs "vale_min" "vale_max" - dans les catalogues - """ - def __init__(self,low,high): - self.low=low - self.high=high - self.cata_info="%s doit etre inferieur a %s" %(low,high) - - def info(self): - return "valeur dans l'intervalle %s , %s" %(self.low,self.high) - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - for val in valeur: - if val < self.low :return 0 - if val > self.high:return 0 - return 1 - else: - if valeur < self.low :return 0 - if valeur > self.high:return 0 - return 1 - - def verif_cata(self): - if self.low > self.high : return 0 - return 1 +import types +import traceback +import re +from .N_ASSD import ASSD +from .N_types import is_int, is_float_or_int, is_complex, is_number, is_str, is_sequence +from Extensions.i18n import tr +import six +from six.moves import range -class CardVal(Valid): - """ - Exemple de classe validateur : verification qu'une liste est - d'une longueur superieur a un minimum (min) et inferieure - a un maximum (max). - Susceptible de remplacer les attributs "min" "max" dans les - catalogues - """ - def __init__(self,min='**',max='**'): - self.min=min - self.max=max - self.cata_info="%s doit etre inferieur a %s" % (min,max) - - def info(self): - return "longueur comprise entre %s et %s" % (self.min,self.max) - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - if self.max != '**' and len(valeur) > self.max:return 0 - if self.min != '**' and len(valeur) < self.min:return 0 - return 1 - else: - if self.max != '**' and 1 > self.max:return 0 - if self.min != '**' and 1 < self.min:return 0 - return 1 - - def verif_cata(self): - if self.min != '**' and self.max != '**' and self.min > self.max : return 0 - return 1 - -class PairVal(Valid): - """ - Exemple de classe validateur : verification qu'une valeur - est paire. - Pour une liste on verifie que tous les elements sont - pairs - """ - def __init__(self): - self.cata_info="" - - def info(self): - return "valeur paire" - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - for val in valeur: - if val % 2 != 0:return 0 - return 1 - else: - if valeur % 2 != 0:return 0 - return 1 - -class EnumVal(Valid): - """ - Exemple de classe validateur : verification qu'une valeur - est prise dans une liste de valeurs. - Susceptible de remplacer l attribut "into" dans les catalogues - """ - def __init__(self,into=()): - if type(into) not in (types.ListType,types.TupleType): into=(into,) - self.into=into - self.cata_info="" - - def info(self): - return "valeur dans %s" % `self.into` - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - for val in valeur: - if val not in self.into:return 0 - return 1 - else: - if valeur not in self.into:return 0 - return 1 - -class NoRepeat(Valid): - """ - Verification d'absence de doublons dans la liste. - """ - def __init__(self): - self.cata_info="" - - def info(self): - return ": présence de doublon dans la liste" - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - liste=list(valeur) - for val in liste: - if liste.count(val)!=1 : return 0 - return 1 - else: - return 1 - -class LongStr(Valid): - """ - Verification de la longueur d une chaine - """ - def __init__(self,low,high): - self.low=low - self.high=high - self.cata_info="" - - def info(self): - return "longueur de la chaine entre %s et %s" %(self.low,self.high) - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - for val in valeur: - if len(val) < self.low :return 0 - if len(val) > self.high:return 0 - return 1 - else: - if len(valeur) < self.low :return 0 - if len(valeur) > self.high:return 0 - return 1 - -class OrdList(Valid): - """ - Verification qu'une liste est croissante ou decroissante - """ - def __init__(self,ord): - self.ord=ord - self.cata_info="" - - def info(self): - return "liste %s" % self.ord - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - if self.ord=='croissant': - var=valeur[0] - for val in valeur[1:]: - if valvar:return 0 - var=val - return 1 - else: - return 1 - - -CoercableFuncs = { types.IntType: int, - types.LongType: long, - types.FloatType: float, - types.ComplexType: complex, - types.UnicodeType: unicode } - -class TypeVal(Valid): - """ - Cette classe est un validateur qui controle qu'une valeur - est bien du type Python attendu. - Pour une liste on verifie que tous les elements sont du bon type. - """ - def __init__(self, aType): - if type(aType) != types.TypeType: - aType=type(aType) - self.aType=aType - try: - self.coerce=CoercableFuncs[ aType ] - except: - self.coerce = self.identity - - def info(self): - return "valeur de %s" % self.aType - - def identity ( self, value ): - if type( value ) == self.aType: - return value - raise ValError - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - for val in valeur: - try: - self.coerce(val) - except: + + +class ValError(Exception): + pass + + +def cls_mro(cls): + if hasattr(cls, "__mro__"): + return cls.__mro__ + mro = [cls] + for base in cls.__bases__: + mro.extend(cls_mro(base)) + return mro + + +class Protocol(object): + + def __init__(self, name): + self.registry = {} + self.name = name + self.args = {} + + def register(self, T, A): + self.registry[T] = A + + def adapt(self, obj): + # (a) verifier si l'objet peut s'adapter au protocole + adapt = getattr(obj, '__adapt__', None) + if adapt is not None: + # on demande à l'objet obj de réaliser lui-meme l'adaptation + return adapt(self) + + # (b) verifier si un adapteur est enregistré (si oui l'utiliser) + if self.registry: + for T in cls_mro(obj.__class__): + if T in self.registry: + return self.registry[T](obj, self, **self.args) + + # (c) utiliser l'adapteur par defaut + return self.default(obj, **self.args) + + def default(self, obj, **args): + raise TypeError("Can't adapt %s to %s" % + (obj.__class__.__name__, self.name)) + + +class PProtocol(Protocol): + + """Verificateur de protocole paramétré (classe de base)""" + # Protocole paramétré. Le registre est unique pour toutes les instances. + # La methode register est une methode de classe + registry = {} + + def __init__(self, name, **args): + self.name = name + self.args = args + + def register(cls, T, A): + cls.registry[T] = A + register = classmethod(register) + + +class ListProtocol(Protocol): + + """Verificateur de protocole liste : convertit un objet quelconque en liste pour validation ultérieure""" + + def default(self, obj): + if type(obj) is tuple: + if len(obj) > 0 and obj[0] in ('RI', 'MP'): + # il s'agit d'un complexe ancienne mode. La cardinalite vaut 1 + return (obj,) + else: + return obj + elif type(obj) is list: + return obj + elif obj == None: + # pas de valeur affecte. La cardinalite vaut 0 + return obj + elif is_str(obj): + # il s'agit d'une chaine. La cardinalite vaut 1 + return (obj,) + else: + try: + # si l'objet supporte len, on a la cardinalite + length = len(obj) + return obj + except: + # sinon elle vaut 1 + return (obj,) + +listProto = ListProtocol("list") + + +class TypeProtocol(PProtocol): + + """Verificateur de type parmi une liste de types possibles""" + # pas de registre par instance. Registre unique pour toutes les instances + # de TypeProtocol + registry = {} + + def __init__(self, name, typ=None): + PProtocol.__init__(self, name, typ=typ) + self.typ = typ + + def default(self, obj, typ): + + err = "" + for type_permis in typ: + if type_permis == 'R': + if is_float_or_int(obj): + return obj + elif type_permis == 'I': + if is_int(obj): + return obj + elif type_permis == 'C': + if self.is_complexe(obj): + return obj + elif type_permis == 'TXM': + if is_str(obj): + return obj + elif type_permis == 'shell': + if is_str(obj): + return obj + elif type_permis == 'Fichier': + import os + try : + if (len(typ) > 2 and typ[2] == "Sauvegarde") or os.path.isfile(obj): + return obj + else: + raise ValError( "%s n'est pas un fichier valide" % repr(obj)) + except : + raise ValError( "%s n'est pas un fichier valide" % repr(obj)) + + elif type_permis == 'FichierNoAbs': + import os + if (len(typ) > 2 and typ[2] == "Sauvegarde") or isinstance(obj, type("")): + return obj + else: + raise ValError( "%s n'est pas un fichier valide" % repr(obj)) + + elif type_permis == 'Repertoire': + import os + try : + if os.path.isdir(obj): return obj + else: raise ValError( "%s n'est pas un repertoire valide" % repr(obj)) + except : + raise ValError( "%s n'est pas un repertoire valide" % repr(obj)) + elif type_permis == 'FichierOuRepertoire': + import os + try : + if os.path.isdir(obj) or os.path.isfile(obj): return obj + else: raise ValError( "%s n'est pas un fichier ou un repertoire valide" % repr(obj)) + except : + raise ValError( "%s n'est pas un fichier ou un repertoire valide" % repr(obj)) + elif type(type_permis) == type or isinstance(type_permis, type): + try: + if self.is_object_from(obj, type_permis): + return obj + except Exception as err: + pass + elif type(type_permis) == types.InstanceType or isinstance(type_permis, object): + try: + if type_permis.__convert__(obj): + return obj + except Exception as err: + pass + else: + print(("Type non encore gere %s" %type_permis)) + raise ValError( + tr("%s (de type %s) n'est pas d'un type autorise: %s %s") % (repr(obj), type(obj), typ, err)) + + def is_complexe(self, valeur): + """ Retourne 1 si valeur est un complexe, 0 sinon """ + if is_number(valeur): + # Pour permettre l'utilisation de complexes Python (accepte les + # entiers et réels) + return 1 + elif type(valeur) != tuple: + # On n'autorise pas les listes pour les complexes + return 0 + elif len(valeur) != 3: + return 0 + else: + # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere + # valeur suivie de 2 reels. + if valeur[0].strip() in ('RI', 'MP'): + try: + v1 = reelProto.adapt(valeur[1]), reelProto.adapt(valeur[2]) + return 1 + except: return 0 - return 1 - else: - try: - self.coerce(valeur) - except: + else: return 0 - return 1 - -class InstanceVal(Valid): - """ - Cette classe est un validateur qui controle qu'une valeur est - bien une instance (au sens Python) d'une classe - Pour une liste on verifie chaque element de la liste - """ - def __init__(self,aClass): - if type(aClass) == types.InstanceType: - aClass=aClass.__class__ - self.aClass=aClass - - def info(self): - return "valeur d'instance de %s" % self.aClass.__name__ - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - for val in valeur: - if not isinstance(val,self.aClass): return 0 - return 1 - if not isinstance(valeur,self.aClass): return 0 - return 1 -def ImpairVal(valeur): + def is_object_from(self, objet, classe): + """ + Retourne 1 si objet est une instance de la classe classe, 0 sinon + """ + convert = getattr(classe, '__convert__', None) + if convert is not None: + # classe verifie les valeurs + try: + v = convert(objet) + return v is not None + except ValueError as err: + raise + except: + return 0 + # On accepte les instances de la classe et des classes derivees + return isinstance(objet, classe) + +reelProto = TypeProtocol("reel", typ=('R',)) + + +class CardProtocol(PProtocol): + + """Verificateur de cardinalité """ + # pas de registre par instance. Registre unique pour toutes les instances + registry = {} + + def __init__(self, name, min=1, max=1): + PProtocol.__init__(self, name, min=min, max=max) + + def default(self, obj, min, max): + length = len(obj) + if (length < min) or( length > max): + raise ValError( + "Nombre d'arguments de %s incorrect (min = %s, max = %s)" % (repr(obj), min, max)) + return obj + + +class IntoProtocol(PProtocol): + + """Verificateur de choix possibles : liste discrète ou intervalle""" + # pas de registre par instance. Registre unique pour toutes les instances + registry = {} + + def __init__(self, name, into=None, val_min=float('-inf'), val_max=float('inf')): + + PProtocol.__init__( + self, name, into=into, val_min=val_min, val_max=val_max) + self.val_min = val_min + self.val_max = val_max + + def default(self, obj, into, val_min, val_max): + if type(into) ==types.FunctionType : + maListeDeValeur=into() + into=maListeDeValeur + if into: + if obj not in into: + raise ValError( + tr("La valeur : %s ne fait pas partie des choix possibles %s") % (repr(obj), into)) + else: + # on est dans le cas d'un ensemble continu de valeurs possibles + # (intervalle) + if is_float_or_int(obj): + if val_min == '**': + val_min = obj - 1 + if val_max == '**': + val_max = obj + 1 + if obj < val_min or obj > val_max: + raise ValError( + tr("La valeur : %s est en dehors du domaine de validite [ %s , %s ]") %(repr(obj), self.val_min, self.val_max)) + return obj + + +class MinStr(object): + # exemple de classe pour verificateur de type + # on utilise des instances de classe comme type (typ=MinStr(3,6), par + # exemple) + + def __init__(self, min, max): + self.min = min + self.max = max + + def __convert__(self, valeur): + if is_str(valeur) and self.min <= len(valeur) <= self.max: return valeur + raise ValError( + "%s n'est pas une chaine de longueur comprise entre %s et %s" % (valeur, self.min, self.max)) + + def __repr__(self): + return tr("TXM de longueur entre %s et %s" % (self.min, self.max)) + + +class Valid(PProtocol): + """ - Cette fonction est un validateur. Elle verifie que la valeur passee - est bien un nombre impair. + Cette classe est la classe mere des validateurs Accas + Elle doit etre derivee + Elle presente la signature des methodes indispensables pour son bon + fonctionnement et dans certains cas leur comportement par défaut. + + @ivar cata_info: raison de la validite ou de l'invalidite du validateur meme + @type cata_info: C{} """ - if type(valeur) in (types.ListType,types.TupleType): - for val in valeur: - if val % 2 != 1:return 0 - return 1 - else: - if valeur % 2 != 1:return 0 - return 1 + registry = {} -ImpairVal.info="valeur impaire" - -class F1Val(Valid): - """ - Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie - que la somme des cles A et B vaut une valeur donnee - en parametre du validateur - """ - def __init__(self,somme=10): - self.somme=somme - self.cata_info="" - - def info(self): - return "valeur %s pour la somme des cles A et B " % self.somme - - def verif(self,valeur): - if type(valeur) in (types.ListType,types.TupleType): - for val in valeur: - if not val.has_key("A"):return 0 - if not val.has_key("B"):return 0 - if val["A"]+val["B"] != self.somme:return 0 - return 1 - else: - if not valeur.has_key("A"):return 0 - if not valeur.has_key("B"):return 0 - if valeur["A"]+valeur["B"] != self.somme:return 0 - return 1 + def __init__(self, **args): + PProtocol.__init__(self, "valid", **args) -class FunctionVal(Valid): - """ - Cette classe est un validateur qui est initialise avec une fonction - """ - def __init__(self,function): - self.function=function + def info(self): + """ + Cette methode retourne une chaine de caractères informative sur + la validation demandée par le validateur. Elle est utilisée + pour produire le compte-rendu de validité du mot clé associé. + """ + return "valeur valide" + + def aide(self): + """ + Cette methode retourne une chaine de caractère qui permet + de construire un message d'aide en ligne. + En général, le message retourné est le meme que celui retourné par la + méthode info. + """ + return self.info() + + def info_erreur_item(self): + """ + Cette méthode permet d'avoir un message d'erreur pour un item + dans une liste dans le cas ou le validateur fait des vérifications + sur les items d'une liste. Si le validateur fait seulement des + vérifications sur la liste elle meme et non sur ses items, la méthode + doit retourner une chaine vide. + """ + return " " + + def info_erreur_liste(self): + """ + Cette méthode a un comportement complémentaire de celui de + info_erreur_item. Elle retourne un message d'erreur lié uniquement + aux vérifications sur la liste elle meme et pas sur ses items. + Dans le cas où le validateur ne fait pas de vérification sur des + listes, elle retourne une chaine vide + """ + return " " + + def verif(self, valeur): + """ + Cette methode sert a verifier si la valeur passee en argument est consideree + comme valide ou non par le validateur. Dans le premier cas le validateur retourne 1 + (valide) sinon 0 (invalide). + + @type valeur: tout type python + @param valeur: valeur du mot cle a valider + @rtype: C{boolean} + @return: indicateur de validite 1 (valide) ou 0 (invalide) + """ + raise NotImplementedError("Must be implemented") + + def verif_item(self, valeur): + """ + La methode verif du validateur effectue une validation complete de + la valeur. valeur peut etre un scalaire ou une liste. Le validateur + doit traiter les 2 aspects s'il accepte des listes (dans ce cas la + methode is_list doit retourner 1). + La methode valid_item sert pour effectuer des validations partielles + de liste. Elle doit uniquement verifier la validite d'un item de + liste mais pas les caracteristiques de la liste. + """ + return 0 + + def valide_liste_partielle(self, liste_courante): + """ + Cette methode retourne un entier qui indique si liste_courante est partiellement valide (valeur 1) + ou invalide (valeur 0). La validation partielle concerne les listes en cours de construction : on + veut savoir si la liste en construction peut etre complétée ou si elle peut déjà etre considérée + comme invalide. + En général un validateur effectue la meme validation pour les listes partielles et les + listes complètes. + """ + return self.verif(liste_courante) + + def verif_cata(self): + """ + Cette methode sert a realiser des verifications du validateur lui meme. + Elle est facultative et retourne 1 (valide) par defaut. + Elle retourne 0 si le validateur est lui meme invalide si par exemple ses + parametres de definition ne sont pas corrects. + La raison de l'invalidite est stockee dans l'attribut cata_info. + + @rtype: C{boolean} + @return: indicateur de validite 1 (valide) ou 0 (invalide) + """ + return 1 + + def is_list(self): + """ + Cette méthode retourne un entier qui indique si le validateur + permet les listes (valeur 1) ou ne les permet pas (valeur 0). + Par défaut, un validateur n'autorise que des scalaires. + """ + return 0 + + def has_into(self): + """ + Cette méthode retourne un entier qui indique si le validateur + propose une liste de choix (valeur 1) ou n'en propose pas. + Par défaut, un validateur n'en propose pas. + """ + return 0 + + def get_into(self, liste_courante=None, into_courant=None): + """ + Cette méthode retourne la liste de choix proposée par le validateur. + Si le validateur ne propose pas de liste de choix, la méthode + retourne None. + L'argument d'entrée liste_courante, s'il est différent de None, donne + la liste des choix déjà effectués par l'utilisateur. Dans ce cas, la + méthode get_into doit calculer la liste des choix en en tenant + compte. Par exemple, si le validateur n'autorise pas les répétitions, + la liste des choix retournée ne doit pas contenir les choix déjà + contenus dans liste_courante. + L'argument d'entrée into_courant, s'il est différent de None, donne + la liste des choix proposés par d'autres validateurs. Dans ce cas, + la méthode get_into doit calculer la liste des choix à retourner + en se limitant à cette liste initiale. Par exemple, si into_courant + vaut (1,2,3) et que le validateur propose la liste de choix (3,4,5), + la méthode ne doit retourner que (3,). + + La méthode get_into peut retourner une liste vide [], ce qui veut + dire qu'il n'y a pas (ou plus) de choix possible. Cette situation + peut etre normale : l''utilisateur a utilisé tous les choix, ou + résulter d'une incohérence des validateurs : + choix parmi (1,2,3) ET choix parmi (4,5,6). Il est impossible de + faire la différence entre ces deux situations. + """ + return into_courant + + +class ListVal(Valid): + + """ + Cette classe sert de classe mère pour tous les validateurs qui acceptent + des listes. + """ + + def is_list(self): + return 1 + + def get_into(self, liste_courante=None, into_courant=None): + """ + Cette méthode get_into effectue un traitement général qui consiste + a filtrer la liste de choix into_courant, si elle existe, en ne + conservant que les valeurs valides (appel de la méthode valid). + """ + if into_courant is None: + return None + else: + liste_choix = [] + for e in into_courant: + if self.verif(e): + liste_choix.append(e) + return liste_choix + + def convert(self, valeur): + """ + Méthode convert pour les validateurs de listes. Cette méthode + fait appel à la méthode convert_item sur chaque élément de la + liste. + """ + if is_sequence(valeur): + for val in valeur: + self.convert_item(val) + return valeur + else: + return self.convert_item(valeur) + + def verif(self, valeur): + """ + Méthode verif pour les validateurs de listes. Cette méthode + fait appel à la méthode verif_item sur chaque élément de la + liste. Si valeur est un paramètre, on utilise sa valeur effective + valeur.valeur. + """ + if is_sequence(valeur): + for val in valeur: + if not self.verif_item(val): + return 0 + return 1 + else: + return self.verif_item(valeur) + + +class Compulsory(ListVal): + """ + Validateur operationnel + Verification de la présence obligatoire d'un élément dans une liste + """ + registry = {} + + def __init__(self, elem=()): + if not is_sequence(elem): + elem = (elem,) + Valid.__init__(self, elem=elem) + self.elem = elem + self.cata_info = "" + + def info(self): + return (tr(u"valeur %s obligatoire") % self.elem) + + def default(self, valeur, elem): + return valeur + + def verif_item(self, valeur): + return 1 + + def convert(self, valeur): + elem = list(self.elem) + for val in valeur: + v = self.adapt(val) + if v in elem: + elem.remove(v) + if elem: + raise ValError( + tr("%s ne contient pas les elements obligatoires : %s ") % (valeur, elem)) + return valeur + + def has_into(self): + return 1 - def info(self): - return self.function.info + def verif(self, valeur): + if not is_sequence(valeur): + liste = list(valeur) + else: + liste = valeur + for val in self.elem: + if val not in liste: + return 0 + return 1 + + def info_erreur_item(self): + return tr("La valeur n'est pas dans la liste des choix possibles") + + +class Together(ListVal): + """ + Validateur operationnel + si un des éléments est présent les autres doivent aussi l'être + """ + registry = {} + + def __init__(self, elem=()): + if not is_sequence(elem): + elem = (elem,) + Valid.__init__(self, elem=elem) + self.elem = elem + self.cata_info = "" + + def info(self): + return (tr("%s present ensemble") % self.elem) + + def default(self, valeur, elem): + return valeur + + def verif_item(self, valeur): + return 1 + + def convert(self, valeur): + elem = list(self.elem) + for val in valeur: + v = self.adapt(val) + if v in elem: elem.remove(v) + if ( len(elem) == 0 ): return valeur + if len(elem) != len(list(self.elem)) : + raise ValError(tr("%s ne contient pas les elements devant etre presents ensemble: %s ") %( valeur, elem)) + return valeur + + def has_into(self): + return 1 + + def verif(self, valeur): + if not is_sequence(valeur): + liste = list(valeur) + else: + liste = valeur + compte = 0 + for val in self.elem: + if val in liste: compte += 1 + if ( compte == 0 ): return 1 + if ( compte != len( list(self.elem) ) ): return 0 + return 1 + + def info_erreur_item(self): + return tr("La valeur n'est pas dans la liste des choix possibles") + + +class Absent(ListVal): + """ + Validateur operationnel + si un des éléments est présent non valide + """ + registry = {} + + def __init__(self, elem=()): + if not is_sequence(elem): + elem = (elem,) + Valid.__init__(self, elem=elem) + self.elem = elem + self.cata_info = "" + + def info(self): + return (tr("%s absent") % self.elem) + + def default(self, valeur, elem): + return valeur + + def verif_item(self, valeur): + return 1 + + def convert(self, valeur): + elem = list(self.elem) + for val in valeur: + v = self.adapt(val) + if v in elem: + raise ValError(tr("%s n'est pas autorise : %s ")% (v, elem)) + return valeur + + def has_into(self): + return 1 + + def verif(self, valeur): + if not is_sequence(valeur): + liste = list(valeur) + else: + liste = valeur + for val in self.elem: + if val in liste: return 0 + return 1 + + def info_erreur_item(self): + return tr("La valeur n'est pas dans la liste des choix possibles") + + +class NoRepeat(ListVal): + """ + Validateur operationnel + Verification d'absence de doublons dans la liste. + """ + def __init__(self): + Valid.__init__(self) + self.cata_info = "" + + def info(self): + return tr("Pas de doublon dans la liste") + + def info_erreur_liste(self): + return tr("Les doublons ne sont pas permis") + + def default(self, valeur): + if valeur in self.liste: + raise ValError( tr("%s est un doublon") % valeur) + return valeur + + def convert(self, valeur): + self.liste = [] + for val in valeur: + v = self.adapt(val) + self.liste.append(v) + return valeur + + def verif_item(self, valeur): + return 1 + + def verif(self, valeur): + if is_sequence(valeur): + liste = list(valeur) + for val in liste: + if liste.count(val) != 1: + return 0 + return 1 + else: + return 1 + + def get_into(self, liste_courante=None, into_courant=None): + """ + Methode get_into spécifique pour validateur NoRepeat, on retourne + une liste de choix qui ne contient aucune valeur de into_courant + déjà contenue dans liste_courante + """ + if into_courant is None: + liste_choix = None + else: + liste_choix = [] + for e in into_courant: + if e in liste_choix: + continue + if liste_courante is not None and e in liste_courante: + continue + liste_choix.append(e) + return liste_choix + + +class LongStr(ListVal): + + """ + Validateur operationnel + Verification de la longueur d une chaine + """ + + def __init__(self, low, high): + ListVal.__init__(self, low=low, high=high) + self.low = low + self.high = high + self.cata_info = "" + + def info(self): + return (tr("longueur de la chaine entre %s et %s") %( self.low, self.high)) + + def info_erreur_item(self): + return tr("Longueur de la chaine incorrecte") + + def convert(self, valeur): + for val in valeur: + v = self.adapt(val) + return valeur + + def verif_item(self, valeur): + try: + self.adapt(valeur) + return 1 + except: + return 0 + + def default(self, valeur, low, high): + if not is_str(valeur): + raise ValError ("%s n'est pas une chaine" % repr(valeur)) + if valeur[0] == "'" and valeur[-1] == "'": + low = low + 2 + high = high + 2 + if len(valeur) < low or len(valeur) > high: + raise ValError( + "%s n'est pas de la bonne longueur" % repr(valeur)) + return valeur + + +class OnlyStr(ListVal): + + """ + Validateur operationnel + Valide que c'est une chaine + """ + + def __init__(self): + ListVal.__init__(self) + self.cata_info = "" + + def info(self): + return tr("regarde si c'est une chaine") + + def info_erreur_item(self): + return tr("Ce n'est pas une chaine") + + def convert(self, valeur): + for val in valeur: + v = self.adapt(val) + return valeur + + def verif_item(self, valeur): + try: + self.adapt(valeur) + return 1 + except: + return 0 + + def default(self, valeur): + if not is_str(valeur): + raise ValError (tr("%s n'est pas une chaine") % repr(valeur)) + return valeur + + +class OrdList(ListVal): + + """ + Validateur operationnel + Verification qu'une liste est croissante ou decroissante + """ + + def __init__(self, ord): + ListVal.__init__(self, ord=ord) + self.ord = ord + self.cata_info = "" + + def info(self): + return ("liste %s" % self.ord) + + def info_erreur_liste(self): + return (tr("La liste doit etre en ordre %s") % self.ord) + + def convert(self, valeur): + self.val = None + self.liste = valeur + for v in valeur: + self.adapt(v) + return valeur + + def default(self, valeur, ord): + if self.ord == 'croissant': + if self.val is not None and valeur < self.val: + raise ValError( + (tr("%s n'est pas par valeurs croissantes") % repr(self.liste))) + elif self.ord == 'decroissant': + if self.val is not None and valeur > self.val: + raise ValError( + (tr("%s n'est pas par valeurs decroissantes") % repr(self.liste))) + self.val = valeur + return valeur + + def verif_item(self, valeur): + return 1 + + def get_into(self, liste_courante=None, into_courant=None): + """ + Methode get_into spécifique pour validateur OrdList, on retourne + une liste de choix qui ne contient aucune valeur de into_courant + dont la valeur est inférieure à la dernière valeur de + liste_courante, si elle est différente de None. + """ + if into_courant is None: + return None + elif not liste_courante: + return into_courant + else: + liste_choix = [] + last_val = liste_choix[-1] + for e in into_courant: + if self.ord == 'croissant' and e <= last_val: + continue + if self.ord == 'decroissant' and e >= last_val: + continue + liste_choix.append(e) + return liste_choix - def verif(self,valeur): - return self.function(valeur) class OrVal(Valid): - """ - Cette classe est un validateur qui controle une liste de validateurs - Elle verifie qu'au moins un des validateurs de la liste a valide la valeur - """ - def __init__(self,validators=()): - if type(validators) not in (types.ListType,types.TupleType): validators=(validators,) - self.validators=[] - for validator in validators: - if type(validator) == types.FunctionType: - self.validators.append(FunctionVal(validator)) - else: - self.validators.append(validator) - self.cata_info="" - - def info(self): - return "\n ou ".join([v.info() for v in self.validators]) - - def verif(self,valeur): - for validator in self.validators: - v=validator.verif(valeur) - if v : - return 1 - return 0 - - def verif_cata(self): - infos=[] - for validator in self.validators: - v=validator.verif_cata() - if not v :infos.append(validator.cata_info) - if infos: - self.cata_info="\n".join(infos) - return 0 - self.cata_info="" - return 1 + + """ + Validateur operationnel + Cette classe est un validateur qui controle une liste de validateurs + Elle verifie qu'au moins un des validateurs de la liste valide la valeur + """ + + def __init__(self, validators=()): + if not is_sequence(validators): + validators = (validators,) + self.validators = [] + for validator in validators: + if type(validator) == types.FunctionType: + self.validators.append(FunctionVal(validator)) + else: + self.validators.append(validator) + self.cata_info = "" + + def info(self): + return "\n ou ".join([v.info() for v in self.validators]) + + def convert(self, valeur): + for validator in self.validators: + try: + return validator.convert(valeur) + except: + pass + raise ValError(tr("%s n'est pas du bon type")% repr(valeur)) + + def info_erreur_item(self): + l = [] + for v in self.validators: + err = v.info_erreur_item() + if err != " ": + l.append(err) + chaine = " \n ou ".join(l) + return chaine + + def info_erreur_liste(self): + l = [] + for v in self.validators: + err = v.info_erreur_liste() + if err != " ": + l.append(err) + chaine = " \n ou ".join(l) + return chaine + + def is_list(self): + """ + Si plusieurs validateurs sont reliés par un OU + il suffit qu'un seul des validateurs attende une liste + pour qu'on considère que leur union attend une liste. + """ + for validator in self.validators: + v = validator.is_list() + if v: + return 1 + return 0 + + def verif(self, valeur): + for validator in self.validators: + v = validator.verif(valeur) + if v: + return 1 + return 0 + + def verif_item(self, valeur): + for validator in self.validators: + v = validator.verif_item(valeur) + if v: + return 1 + return 0 + + def verif_cata(self): + infos = [] + for validator in self.validators: + v = validator.verif_cata() + if not v: + infos.append(validator.cata_info) + if infos: + self.cata_info = "\n".join(infos) + return 0 + self.cata_info = "" + return 1 + + def has_into(self): + """ + Dans le cas ou plusieurs validateurs sont reliés par un OU + il faut que tous les validateurs proposent un choix pour + qu'on considère que leur union propose un choix. + Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix + En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un choix (1,2,3,4,5,6) + """ + for validator in self.validators: + v = validator.has_into() + if not v: + return 0 + return 1 + + def get_into(self, liste_courante=None, into_courant=None): + """ + Dans le cas ou plusieurs validateurs sont reliés par un OU + tous les validateurs doivent proposer un choix pour + qu'on considère que leur union propose un choix. Tous les choix + proposés par les validateurs sont réunis (opérateur d'union). + Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix + En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un + choix (1,2,3,4,5,6) + """ + validator_into = [] + for validator in self.validators: + v_into = validator.get_into(liste_courante, into_courant) + if v_into is None: + return v_into + validator_into.extend(v_into) + return validator_into + + def valide_liste_partielle(self, liste_courante=None): + """ + Méthode de validation de liste partielle pour le validateur Or. + Si un des validateurs gérés par le validateur Or considère la + liste comme valide, le validateur Or la considère comme valide. + """ + for validator in self.validators: + v = validator.valide_liste_partielle(liste_courante) + if v: + return 1 + return 0 + class AndVal(Valid): - """ - Cette classe est un validateur qui controle une liste de validateurs - Elle verifie que tous les validateurs de la liste sont positifs - """ - def __init__(self,validators=()): - if type(validators) not in (types.ListType,types.TupleType): validators=(validators,) - self.validators=[] - for validator in validators: - if type(validator) == types.FunctionType: - self.validators.append(FunctionVal(validator)) - else: - self.validators.append(validator) - self.cata_info="" - - def info(self): - return " et ".join([v.info() for v in self.validators]) - - def verif(self,valeur): - for validator in self.validators: - v=validator.verif(valeur) - if not v : - self.local_info=validator.info() - return 0 - return 1 - - def verif_cata(self): - infos=[] - for validator in self.validators: - v=validator.verif_cata() - if not v :infos.append(validator.cata_info) - if infos: - self.cata_info="\n".join(infos) - return 0 - self.cata_info="" - return 1 + + """ + Validateur operationnel + Cette classe est un validateur qui controle une liste de validateurs + Elle verifie que tous les validateurs de la liste valident la valeur + """ + + def __init__(self, validators=()): + if not is_sequence(validators): + validators = (validators,) + self.validators = [] + for validator in validators: + if type(validator) == types.FunctionType: + self.validators.append(FunctionVal(validator)) + else: + self.validators.append(validator) + if hasattr(validator, 'fonctions'): + for fonction in validator.fonctions: + f = getattr(validator, fonction) + setattr(self, fonction, f) + self.cata_info = "" + + def info(self): + return "\n et ".join([v.info() for v in self.validators]) + + def convert(self, valeur): + for validator in self.validators: + valeur = validator.convert(valeur) + return valeur + + def info_erreur_item(self): + chaine = "" + a = 1 + for v in self.validators: + if v.info_erreur_item() != " ": + if a == 1: + chaine = v.info_erreur_item() + a = 0 + else: + chaine = chaine + " \n et " + v.info_erreur_item() + return chaine + + def info_erreur_liste(self): + chaine="" + a = 1 + for v in self.validators: + if v.info_erreur_liste() != " ": + if a == 1: + chaine = v.info_erreur_liste() + a = 0 + else: + chaine = chaine + " \n et " + v.info_erreur_liste() + return chaine + + def verif(self, valeur): + for validator in self.validators: + v = validator.verif(valeur) + if not v: + self.local_info = validator.info() + return 0 + return 1 + + def verif_item(self, valeur): + for validator in self.validators: + v = validator.verif_item(valeur) + if not v: + # L'info n'est probablement pas la meme que pour verif ??? + self.local_info = validator.info() + return 0 + return 1 + + def verif_cata(self): + infos = [] + for validator in self.validators: + v = validator.verif_cata() + if not v: + infos.append(validator.cata_info) + if infos: + self.cata_info = "\n".join(infos) + return 0 + self.cata_info = "" + return 1 + + def valide_liste_partielle(self, liste_courante=None): + """ + Méthode de validation de liste partielle pour le validateur And. + Tous les validateurs gérés par le validateur And doivent considérer + la liste comme valide, pour que le validateur And la considère + comme valide. + """ + for validator in self.validators: + v = validator.valide_liste_partielle(liste_courante) + if not v: + return 0 + return 1 + + def is_list(self): + """ + Si plusieurs validateurs sont reliés par un ET + il faut que tous les validateurs attendent une liste + pour qu'on considère que leur intersection attende une liste. + Exemple Range(2,5) ET Card(1) n'attend pas une liste + Range(2,5) ET Pair attend une liste + """ + for validator in self.validators: + v = validator.is_list() + if v == 0: + return 0 + return 1 + + def has_into(self): + """ + Dans le cas ou plusieurs validateurs sont reliés par un ET + il suffit qu'un seul validateur propose un choix pour + qu'on considère que leur intersection propose un choix. + Exemple : Enum(1,2,3) ET entier pair, propose un choix + En revanche, entier pair ET superieur à 10 ne propose pas de choix + """ + for validator in self.validators: + v = validator.has_into() + if v: + return 1 + return 0 + + def get_into(self, liste_courante=None, into_courant=None): + """ + Dans le cas ou plusieurs validateurs sont reliés par un ET + il suffit qu'un seul validateur propose un choix pour + qu'on considère que leur intersection propose un choix. Tous les + choix proposés par les validateurs sont croisés (opérateur + d'intersection) + Exemple : Enum(1,2,3) ET entier pair, propose un choix (2,) + En revanche, Enum(1,2,3) ET Enum(4,5,6) ne propose pas de choix. + """ + for validator in self.validators: + into_courant = validator.get_into(liste_courante, into_courant) + if into_courant in ([], None): + break + return into_courant + def do_liste(validators): - """ + """ Convertit une arborescence de validateurs en OrVal ou AndVal validators est une liste de validateurs ou de listes ou de tuples """ - valids=[] + valids = [] for validator in validators: if type(validator) == types.FunctionType: - valids.append(FunctionVal(validator)) - elif type(validator) == types.TupleType: - valids.append(OrVal(do_liste(validator))) - elif type(validator) == types.ListType: - valids.append(AndVal(do_liste(validator))) + valids.append(FunctionVal(validator)) + elif type(validator) is tuple: + valids.append(OrVal(do_liste(validator))) + elif type(validator) is list: + valids.append(AndVal(do_liste(validator))) else: - valids.append(validator) + valids.append(validator) return valids + def validatorFactory(validator): if type(validator) == types.FunctionType: - return FunctionVal(validator) - elif type(validator) == types.TupleType: - return OrVal(do_liste(validator)) - elif type(validator) == types.ListType: - return AndVal(do_liste(validator)) + return FunctionVal(validator) + elif type(validator) is tuple: + return OrVal(do_liste(validator)) + elif type(validator) is list: + return AndVal(do_liste(validator)) else: - return validator + return validator + +# Ci-dessous : exemples de validateur (peu testés) + + +class RangeVal(ListVal): + + """ + Exemple de classe validateur : verification qu'une valeur + est dans un intervalle. + Pour une liste on verifie que tous les elements sont + dans l'intervalle + Susceptible de remplacer les attributs "vale_min" "vale_max" + dans les catalogues + """ + + def __init__(self, low, high): + self.low = low + self.high = high + self.cata_info = (tr("%s doit etre inferieur a %s") % (low, high)) + + def info(self): + return (tr("valeur dans l'intervalle %s , %s") %( self.low, self.high)) + + def convert_item(self, valeur): + if valeur > self.low and valeur < self.high: + return valeur + raise ValError(tr("%s devrait etre comprise entre %s et %s") % (valeur, self.low, self.high)) + + def verif_item(self, valeur): + return valeur > self.low and valeur < self.high + + def info_erreur_item(self): + return (tr("la valeur %s doit etre comprise entre %s et %s") % (valeur, self.low, self.high)) + + + def verif_cata(self): + if self.low > self.high: + return 0 + return 1 + + +class CardVal(Valid): + + """ + Exemple de classe validateur : verification qu'une liste est + d'une longueur superieur a un minimum (min) et inferieure + a un maximum (max). + Susceptible de remplacer les attributs "min" "max" dans les + catalogues + """ + + def __init__(self, min=float('-inf'), max=float('inf')): + self.min = min + self.max = max + self.cata_info = (tr("%s doit etre inferieur a %s") %(min, max)) + + def info(self): + return (tr("longueur de liste comprise entre %s et %s") %(self.min, self.max)) + + def info_erreur_liste(self): + return (tr("Le cardinal de la liste doit etre compris entre %s et %s") % (self.min, self.max)) + + def is_list(self): + return self.max == '**' or self.max > 1 + + def get_into(self, liste_courante=None, into_courant=None): + if into_courant is None: + return None + elif liste_courante is None: + return into_courant + elif self.max == '**': + return into_courant + elif len(liste_courante) < self.max: + return into_courant + else: + return [] + + def convert(self, valeur): + if is_sequence(valeur): + l = len(valeur) + elif valeur is None: + l = 0 + else: + l = 1 + if self.max != '**' and l > self.max: + raise ValError( + tr("%s devrait etre de longueur inferieure a %s") % (valeur, self.max)) + if self.min != '**' and l < self.min: + raise ValError( + tr("%s devrait etre de longueur superieure a %s") % (valeur, self.min)) + return valeur + + def verif_item(self, valeur): + return 1 + + def verif(self, valeur): + if is_sequence(valeur): + if self.max != '**' and len(valeur) > self.max: + return 0 + if self.min != '**' and len(valeur) < self.min: + return 0 + return 1 + else: + if self.max != '**' and 1 > self.max: + return 0 + if self.min != '**' and 1 < self.min: + return 0 + return 1 + + def verif_cata(self): + if self.min != '**' and self.max != '**' and self.min > self.max: + return 0 + return 1 + + def valide_liste_partielle(self, liste_courante=None): + validite = 1 + if liste_courante != None: + if len(liste_courante) > self.max: + validite = 0 + return validite + + +class PairVal(ListVal): + + """ + Exemple de classe validateur : verification qu'une valeur + est paire. + Pour une liste on verifie que tous les elements sont + pairs + """ + + def __init__(self): + ListVal.__init__(self) + self.cata_info = "" + + def info(self): + return _(u"valeur paire") + + def info_erreur_item(self): + return tr("La valeur saisie doit etre paire") + + def convert(self, valeur): + for val in valeur: + v = self.adapt(val) + if v % 2 != 0: + raise ValError( + tr("%s contient des valeurs non paires") % repr(valeur)) + return valeur + + def default(self, valeur): + return valeur + + def verif_item(self, valeur): + if type(valeur) not in six.integer_types: + return 0 + return valeur % 2 == 0 + + def verif(self, valeur): + if is_sequence(valeur): + for val in valeur: + if val % 2 != 0: + return 0 + return 1 + else: + if valeur % 2 != 0: + return 0 + return 1 + + +class EnumVal(ListVal): + + """ + Exemple de classe validateur : verification qu'une valeur + est prise dans une liste de valeurs. + Susceptible de remplacer l attribut "into" dans les catalogues + """ + + def __init__(self, into=()): + if not is_sequence(into): + into = (into,) + self.into = into + self.cata_info = "" + + def info(self): + return ("valeur dans %s" % self.into) + + def convert_item(self, valeur): + if valeur in self.into: + return valeur + raise ValError( + tr("%s contient des valeurs hors des choix possibles: %s ") % (valeur, self.into)) + + def verif_item(self, valeur): + if valeur not in self.into: + return 0 + return 1 + + def has_into(self): + return 1 + + def get_into(self, liste_courante=None, into_courant=None): + if into_courant is None: + liste_choix = list(self.into) + else: + liste_choix = [] + for e in into_courant: + if e in self.into: + liste_choix.append(e) + return liste_choix + + def info_erreur_item(self): + return tr("La valeur n'est pas dans la liste des choix possibles") + + +def ImpairVal(valeur): + """ + Exemple de validateur + Cette fonction est un validateur. Elle verifie que la valeur passee + est bien un nombre impair. + """ + if is_sequence(valeur): + for val in valeur: + if val % 2 != 1: + return 0 + return 1 + else: + if valeur % 2 != 1: + return 0 + return 1 + +ImpairVal.info = "valeur impaire" + + +class F1Val(Valid): + + """ + Exemple de validateur + Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie + que la somme des cles A et B vaut une valeur donnee + en parametre du validateur + """ + + def __init__(self, somme=10): + self.somme = somme + self.cata_info = "" + + def info(self): + return (tr("valeur %s pour la somme des cles A et B ") % self.somme) + + def verif(self, valeur): + if is_sequence(valeur): + for val in valeur: + if not "A" in val: + return 0 + if not "B" in val: + return 0 + if val["A"] + val["B"] != self.somme: + return 0 + return 1 + else: + if not "A" in valeur: + return 0 + if not "B" in valeur: + return 0 + if valeur["A"] + valeur["B"] != self.somme: + return 0 + return 1 + + +class FunctionVal(Valid): + + """ + Exemple de validateur + Cette classe est un validateur qui est initialise avec une fonction + """ + + def __init__(self, function): + self.function = function + + def info(self): + return self.function.info + + def info_erreur_item(self): + return self.function.info + + def verif(self, valeur): + return self.function(valeur) + + def verif_item(self, valeur): + return self.function(valeur) + + def convert(self, valeur): + return valeur + +# MC ca ne devrait plus servir ! +CoercableFuncs = {int: int, + int: int, + float: float, + complex: complex, + str: six.text_type} + + +#class FunctionValObjet(FunctionVal): +#OOOOOOOOOOOOOOo + +class TypeVal(ListVal): + + """ + Exemple de validateur + Cette classe est un validateur qui controle qu'une valeur + est bien du type Python attendu. + Pour une liste on verifie que tous les elements sont du bon type. + Semblable a InstanceVal mais ici on fait le test par tentative de conversion + alors qu'avec InstanceVal on ne teste que si isinstance est vrai. + """ + + def __init__(self, aType): + # Si aType n'est pas un type, on le retrouve a l'aide de la fonction type + # type(1) == int;type(0.2)==float;etc. + if type(aType) != type: + aType = type(aType) + self.aType = aType + try: + self.coerce = CoercableFuncs[aType] + except: + self.coerce = self.identity + + def info(self): + return (tr("valeur de %s") % self.aType) + + def identity(self, value): + if type(value) == self.aType: + return value + raise ValError + + def convert_item(self, valeur): + return self.coerce(valeur) + + def verif_item(self, valeur): + try: + self.coerce(valeur) + except: + return 0 + return 1 + + +class InstanceVal(ListVal): + + """ + Exemple de validateur + Cette classe est un validateur qui controle qu'une valeur est + bien une instance (au sens Python) d'une classe + Pour une liste on verifie chaque element de la liste + """ + + def __init__(self, aClass): + # Si aClass est une classe on la memorise dans self.aClass + # sinon c'est une instance dont on memorise la classe + if type(aClass) == types.InstanceType: + # instance ancienne mode + aClass = aClass.__class__ + elif type(aClass) == type: + # classe ancienne mode + aClass = aClass + elif type(aClass) == type: + # classe nouvelle mode + aClass = aClass + elif isinstance(aClass, object): + # instance nouvelle mode + aClass = type(aClass) + else: + raise ValError(tr("type non supporté")) + + self.aClass = aClass + + def info(self): + return (tr("valeur d'instance de %s") % self.aClass.__name__) + + def verif_item(self, valeur): + if not isinstance(valeur, self.aClass): + return 0 + return 1 + + +class VerifTypeTuple(ListVal): + + def __init__(self, typeDesTuples): + self.typeDesTuples = typeDesTuples + Valid.__init__(self) + self.cata_info = "" + + def info(self): + return tr(": verifie les types dans un tuple") + + def info_erreur_liste(self): + return tr("Les types entres ne sont pas permis") + + def default(self, valeur): + return valeur + + def is_list(self): + return 1 + + def convert_item(self, valeur): + if len(valeur) != len(self.typeDesTuples): + raise ValError( + tr("%s devrait etre de type %s ") %( valeur, self.typeDesTuples)) + for i in range(len(valeur)): + ok = self.verifType(valeur[i], self.typeDesTuples[i]) + if ok != 1: + raise ValError( + tr("%s devrait etre de type %s ") % (valeur, self.typeDesTuples)) + return valeur + + def verif_item(self, valeur): + try: + if len(valeur) != len(self.typeDesTuples): + return 0 + for i in range(len(valeur)): + ok = self.verifType(valeur[i], self.typeDesTuples[i]) + if ok != 1: + return 0 + except: + return 0 + return 1 + + def verifType(self, valeur, type_permis): + if type_permis == 'R': + if type(valeur) in (int, float, int): + return 1 + elif type_permis == 'I': + if type(valeur) in (int, int): + return 1 + elif type_permis == 'C': + if self.is_complexe(valeur): + return 1 + elif type_permis == 'TXM': + if type(valeur) == bytes: + return 1 + elif isinstance(valeur, type_permis): + return 1 + return 0 + + def verif(self, valeur): + if type(valeur) in (list, tuple): + liste = list(valeur) + for val in liste: + if self.verif_item(val) != 1: + return 0 + return 1 + + +class VerifExiste(ListVal): + + """ + fonctionne avec into + Met une liste à jour selon les mot clefs existant + exemple si into = ("A","B","C") + si au niveau N du JDC les objets "A" et "C" existe + alors la liste des into deviendra ( "A","C") + + niveauVerif est le niveau du JDC dans lequel va s effectuer la verification + niveauVerif est defini par rapport au Noeud : + exemple niveauVerif = 1 : on verifie les freres + niveauVerif = 2 : on verifie les oncles.. + """ + + def __init__(self, niveauVerif): + ListVal.__init__(self) + self.niveauVerif = niveauVerif + self.MCSimp = None + self.listeDesFreres = () + self.fonctions = ('verifie_liste', 'set_MCSimp') + + def is_list(self): + return 1 + + def verifie_liste(self, liste): + self.set_MCSimp(self.MCSimp) + for item in liste: + if not(item in self.listeDesFreres): + return 0 + return 1 + + def verif_item(self, valeur): + self.set_MCSimp(self.MCSimp) + if valeur in self.listeDesFreres: + return 1 + return 0 + + def set_MCSimp(self, MCSimp): + self.MCSimp = MCSimp + k = self.niveauVerif + mc = MCSimp + while (k != 0): + parent = mc.parent + mc = parent + k = k - 1 + # on met la liste à jour + parent.forceRecalcul = self.niveauVerif + self.listeDesFreres = parent.liste_mc_presents() + + def convert_item(self, valeur): + if valeur in self.listeDesFreres: + return valeur + raise ValError( + tr("%s n'est pas dans %s") % (valeur, self.listeDesFreres)) + + +class RegExpVal(ListVal): + + """ + Vérifie qu'une chaîne de caractère corresponde à l'expression régulière 'pattern' + """ + + errormsg = 'La chaîne "%(value)s" ne correspond pas au motif "%(pattern)s"' + + def __init__(self, pattern): + self.pattern = pattern + self.compiled_regexp = re.compile(pattern) + + def info(self): + return tr('Une chaîne correspondant au motif ') + str(self.pattern) + tr(" est attendue") + + def info_erreur_item(self): + return tr('Une chaîne correspondant au motif ') + str(self.pattern) + tr(" est attendue") + + def verif_item(self, valeur): + if self.compiled_regexp.match(valeur): + return 1 + else: + return (0, self.errormsg % {"value": valeur, "pattern": self.pattern}) + + def convert_item(self, valeur): + if self.compiled_regexp.match(valeur): + return valeur + else: + raise ValError(self.errormsg % + {"value": valeur, "pattern": self.pattern}) + + +class FileExtVal(RegExpVal): + + """ + Vérifie qu'une chaîne de caractère soit un nom de fichier valide avec l'extension 'ext' + """ + + def __init__(self, ext): + self.ext = ext + self.errormsg = '"%%(value)s" n\'est pas un nom de fichier %(ext)s valide' % { + "ext": ext} + #PNPN Modif pour Adao + RegExpVal.__init__(self, "^\S+\.%s$" % self.ext) + + + def info(self): + return ('Un nom de fichier se terminant par ".%s" est attendu.' % self.ext) + + def info_erreur_item(self): + return ('Un nom de fichier se terminant par ".%s" est attendu.' % self.ext) + +class CreeMotClef(object): + def __init__(self,MotClef ): + self.MotClef=MotClef + self.MCSimp=None + + def convert(self, lval): + try : valeur=lval[0] + except : return lval + + parent= self.MCSimp.parent + if hasattr(parent, 'inhibeValidator') and parent.inhibeValidator: return lval + + + if parent.get_child(self.MotClef) == None : longueur=0 + else : longueur=len(parent.get_child(self.MotClef)) + + pos=parent.get_index_child(self.MCSimp.nom)+1 + while longueur < valeur : + parent.inhibeValidator=1 + parent.addentite(self.MotClef,pos) + pos=pos+1 + parent.inhibeValidator=0 + longueur=len(parent.get_child(self.MotClef)) + + if longueur > valeur : + parent.inhibeValide=1 + parentObj=parent.get_child(self.MotClef) + obj=parent.get_child(self.MotClef)[-1] + parentObj.suppentite(obj) + longueur=len(parent.get_child(self.MotClef)) + parent.inhibeValide=0 + return lval + + def info(self): + return "Cree le bon nombre de Mot %s" % self.MotClef + + def verif_item(self, valeur): + return 1 + + def set_MCSimp(self, MCSimp): + #print "dans set_MCSimp" + self.MCSimp=MCSimp