- """
- """
-
- def isvalid(self,sd='oui',cr='non'):
- """
- Methode pour verifier la validité de l'objet ETAPE. Cette méthode
- peut etre appelée selon plusieurs modes en fonction de la valeur
- de sd et de cr.
-
- Si cr vaut oui elle crée en plus un compte-rendu.
-
- Cette méthode a plusieurs fonctions :
-
- - mettre à jour l'état de self (update)
-
- - retourner un indicateur de validité 0=non, 1=oui
-
- - produire un compte-rendu : self.cr
-
- """
- if CONTEXT.debug : print "ETAPE.isvalid ",self.nom
- if self.state == 'unchanged' :
- return self.valid
- else:
- valid=1
- # On marque les concepts CO pour verification ulterieure de leur bonne utilisation
- l=self.mark_CO()
- # On verifie que les concepts CO sont bien passes par type_sdprod
- for c in l:
- if c.etape is self.parent:
- # le concept est propriete de l'etape parent
- # Il n'a pas ete transforme par type_sdprod
- # Cette situation est interdite
- # Pb: La macro-commande a passe le concept a une commande (macro ?) mal definie
- if cr =='oui':
- self.cr.fatal("Macro-commande mal definie : manque probablement appel a type_sdprod pour %s" % c.nom)
- valid=0
-
- valid=valid * self.valid_child()
- valid=valid * self.valid_regles(cr)
-
- if self.reste_val != {}:
- if cr == 'oui' :
- self.cr.fatal("Mots cles inconnus :" + string.join(self.reste_val.keys(),','))
- valid=0
-
- if sd == "non":
- # Dans ce cas, on ne calcule qu'une validite partielle, on ne modifie pas l'état de self
- # on retourne simplement l'indicateur valid
- return valid
-
- if self.sd != None :
- valid = valid * self.valid_sdnom(cr)
-
- if self.definition.reentrant == 'n' and self.reuse:
- # Il ne peut y avoir de concept reutilise avec une MACRO non reentrante
- if cr == 'oui' : self.cr.fatal('Macro-commande non reentrante : ne pas utiliser reuse ')
- valid=0
-
- if valid:
- valid = self.update_sdprod(cr)
-
- # Si la macro comprend des etapes internes, on teste leur validite
- for e in self.etapes:
- if not e.isvalid():
- valid=0
- break
-
- self.set_valid(valid)
-
- return self.valid
-
- def update_sdprod(self,cr='non'):
- """
- Cette méthode met à jour le concept produit en fonction des conditions initiales :
-
- 1. Il n'y a pas de concept retourné (self.definition.sd_prod == None)
-
- 2. Le concept retourné n existait pas (self.sd == None)
-
- 3. Le concept retourné existait. On change alors son type ou on le supprime
-
- En cas d'erreur (exception) on retourne un indicateur de validité de 0 sinon de 1
- """
- sd_prod=self.definition.sd_prod
- # On memorise le type retourné dans l attribut typret
- self.typret=None
- if type(sd_prod) == types.FunctionType:
- # Type de concept retourné calculé
- d=self.cree_dict_valeurs(self.mc_liste)
- try:
- # la sd_prod d'une macro a l'objet lui meme en premier argument
- # contrairement à une ETAPE ou PROC_ETAPE
- # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute
- # les concepts produits dans self.sdprods, il faut le mettre à zéro
- self.sdprods=[]
- sd_prod= apply(sd_prod,(self,),d)
- except:
- # Erreur pendant le calcul du type retourné
- if CONTEXT.debug:traceback.print_exc()
- self.sd=None
- if cr == 'oui' :
- l=traceback.format_exception(sys.exc_info()[0],
- sys.exc_info()[1],
- sys.exc_info()[2])
- self.cr.fatal('Impossible d affecter un type au résultat\n'+string.join(l[2:]))
- return 0
- # on teste maintenant si la SD est r\351utilis\351e ou s'il faut la cr\351er
- valid=1
- if self.reuse:
- # Un concept reutilise a ete specifie
- if AsType(self.reuse) != sd_prod:
- if cr == 'oui' : self.cr.fatal('Type de concept reutilise incompatible avec type produit')
- valid=0
- if self.sdnom!='':
- if self.sdnom[0] != '_' and self.reuse.nom != self.sdnom:
- # Le nom de la variable de retour (self.sdnom) doit etre le meme que celui du concept reutilise (self.reuse.nom)
- if cr == 'oui' :
- self.cr.fatal('Concept reutilise : le nom de la variable de retour devrait etre %s et non %s' %(self.reuse.nom,self.sdnom))
- valid= 0
- if valid:self.sd=self.reuse
- else:
- #Cas d'un concept non reutilise
- if sd_prod == None:# Pas de concept retourné
- # Que faut il faire de l eventuel ancien sd ?
- self.sd = None
- else:
- if self.sd:
- # Un sd existe deja, on change son type
- if CONTEXT.debug:print "changement de type:",self.sd,sd_prod
- if self.sd.__class__ != sd_prod:
- self.sd.change_type(sd_prod)
- self.typret=sd_prod
- else:
- # Le sd n existait pas , on ne le crée pas
- self.typret=sd_prod
- if cr == 'oui' : self.cr.fatal("Concept retourné non défini")
- valid=0
- if self.definition.reentrant == 'o':
- if cr == 'oui' : self.cr.fatal('Commande obligatoirement reentrante : specifier reuse=concept')
- valid=0
- return valid
-
- def report(self):
- """
- Methode pour la generation d un rapport de validation
- """
- V_ETAPE.ETAPE.report(self)
- for e in self.etapes :
- self.cr.add(e.report())
- return self.cr