2 Ce module contient la classe mixin MACRO_ETAPE qui porte les méthodes
3 nécessaires pour réaliser la validation d'un objet de type MACRO_ETAPE
6 Une classe mixin porte principalement des traitements et est
7 utilisée par héritage multiple pour composer les traitements.
10 import string,types,sys
16 from Noyau.N_Exception import AsException
17 from Noyau.N_utils import AsType
19 class MACRO_ETAPE(V_ETAPE.ETAPE):
23 def isvalid(self,sd='oui',cr='non'):
25 Methode pour verifier la validité de l'objet ETAPE. Cette méthode
26 peut etre appelée selon plusieurs modes en fonction de la valeur
29 Si cr vaut oui elle crée en plus un compte-rendu.
31 Cette méthode a plusieurs fonctions :
33 - mettre à jour l'état de self (update)
35 - retourner un indicateur de validité 0=non, 1=oui
37 - produire un compte-rendu : self.cr
40 if CONTEXT.debug : print "ETAPE.isvalid ",self.nom
41 if self.state == 'unchanged' :
45 if hasattr(self,'valid'):
46 old_valid = self.valid
49 # on teste, si elle existe, le nom de la sd (sa longueur doit être <= 8 caractères)
51 # la SD existe déjà : on regarde son nom
52 if self.sd.get_name() != None :
53 if len(self.sd.nom) > 8 :
55 self.cr.fatal("Le nom de concept %s est trop long (8 caractères maxi)" %self.sd.nom)
57 if string.find(self.sd.nom,'sansnom') != -1 :
58 # la SD est 'sansnom' : --> erreur
60 self.cr.fatal("Pas de nom pour le concept retourné")
62 elif string.find(self.sd.nom,'SD_') != -1 :
63 # la SD est 'SD_' cad son nom = son id donc pas de nom donné par utilisateur : --> erreur
65 self.cr.fatal("Pas de nom pour le concept retourné")
67 # on teste les enfants
68 for child in self.mc_liste :
69 if not child.isvalid():
72 # on teste les règles de self
73 text_erreurs,test_regles = self.verif_regles()
75 if cr == 'oui' : self.cr.fatal(string.join(("Règle(s) non respectée(s) :", text_erreurs)))
77 if self.reste_val != {}:
79 self.cr.fatal("Mots cles inconnus :" + string.join(self.reste_val.keys(),','))
81 if sd == 'oui' and valid:
82 valid = self.update_sdprod(cr)
83 # Si la macro comprend des etapes internes, on teste leur validite
89 self.state = 'unchanged'
91 if old_valid != self.valid : self.init_modif_up()
94 def update_sdprod(self,cr='non'):
96 Cette méthode met à jour le concept produit en fonction des conditions initiales :
98 1- Il n'y a pas de concept retourné (self.definition.sd_prod == None)
100 2- Le concept retourné n existait pas (self.sd == None)
102 3- Le concept retourné existait. On change alors son type ou on le supprime
104 En cas d'erreur (exception) on retourne un indicateur de validité de 0 sinon de 1
106 sd_prod=self.definition.sd_prod
107 # On memorise le type retourné dans l attribut typret
109 if type(sd_prod) == types.FunctionType:
110 # Type de concept retourné calculé
111 d=self.cree_dict_valeurs(self.mc_liste)
113 # la sd_prod d'une macro a l'objet lui meme en premier argument
114 # contrairement à une ETAPE ou PROC_ETAPE
115 # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute
116 # les concepts produits dans self.sdprods, il faut le mettre à zéro
118 sd_prod= apply(sd_prod,(self,),d)
120 # Erreur pendant le calcul du type retourné
121 if CONTEXT.debug:traceback.print_exc()
124 l=traceback.format_exception(sys.exc_info()[0],
127 self.cr.fatal('Impossible d affecter un type au résultat\n'+string.join(l[2:]))
129 # on teste maintenant si la SD est r\351utilis\351e ou s'il faut la cr\351er
131 if AsType(self.reuse) != sd_prod:
132 if cr == 'oui' : self.cr.fatal('Type de concept reutilise incompatible avec type produit')
137 if sd_prod == None:# Pas de concept retourné
138 # Que faut il faire de l eventuel ancien sd ?
142 # Un sd existe deja, on change son type
143 self.sd.__class__=sd_prod
146 # Le sd n existait pas , on ne le crée pas
148 if cr == 'oui' : self.cr.fatal("Concept retourné non défini")
150 if self.definition.reentrant == 'o':
156 Methode pour la generation d un rapport de validation
158 V_ETAPE.ETAPE.report(self)
159 for e in self.etapes :
160 self.cr.add(e.report())