X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=Ihm%2FI_MACRO_ETAPE.py;h=357fc5b783db4caf605f10980c99d792afe3fc83;hb=d41b1c52d0c35b655f6feabfe816a3c541f3a92a;hp=be318d25fbf2c096767eb7c6ee8f483e9ab13758;hpb=fcd054a825fbe171652108194c0204f8e3fd955a;p=tools%2Feficas.git diff --git a/Ihm/I_MACRO_ETAPE.py b/Ihm/I_MACRO_ETAPE.py index be318d25..357fc5b7 100644 --- a/Ihm/I_MACRO_ETAPE.py +++ b/Ihm/I_MACRO_ETAPE.py @@ -1,132 +1,334 @@ +# -*- coding: utf-8 -*- +# CONFIGURATION MANAGEMENT OF EDF VERSION +# ====================================================================== +# COPYRIGHT (C) 1991 - 2002 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. +# +# +# ====================================================================== """ """ # Modules Python +import sys import traceback,types,string # Modules Eficas import I_ETAPE +import I_ENTITE +import I_OBJECT +import Noyau from Noyau.N_ASSD import ASSD +from Noyau import N__F +import convert +from Extensions import param2 + +# import rajoutés suite à l'ajout de Build_sd --> à résorber +import Noyau, Validation.V_MACRO_ETAPE +from Noyau import N_Exception +from Noyau.N_Exception import AsException +import Accas # attention aux imports circulaires +# fin import à résorber class MACRO_ETAPE(I_ETAPE.ETAPE): def __init__(self): - I_ETAPE.ETAPE.__init__(self) + self.typret=None + #indique si le jeu de commande inclus a pu etre analysé par convert + #pour etre editable (0=NON, 1=OUI) + self.text_converted=1 + self.text_error="" + self.recorded_units={} def get_sdprods(self,nom_sd): """ Fonction : retourne le concept produit par l etape de nom nom_sd - s il existe sinon None + s il existe sinon None """ - if self.sd: - if self.sd.nom == nom_sd: - return self.sd + if self.sd and self.sd.nom == nom_sd :return self.sd for co in self.sdprods: - if co.nom==nom_sd:return co + if co.nom == nom_sd:return co + if type(self.definition.op_init) == types.FunctionType: + d={} + apply(self.definition.op_init,(self,d)) + return d.get(nom_sd,None) return None - def make_contexte(self,fichier,text): - """ - Cette méthode sert à créer un contexte en interprétant un texte source - Python - """ - # on récupère le contexte d'un nouveau jdc dans lequel on interprete text - contexte = self.get_contexte_jdc(fichier,text) - if contexte == None : - raise Exception("Impossible de relire le fichier") - else: - self.g_context = contexte - if hasattr(self,'contexte_fichier_init'): - self.old_contexte_fichier_init = self.contexte_fichier_init - self.contexte_fichier_init = contexte - # XXX la validité ne doit pas etre forcée à 1. Que faut-il faire exactement ??? - self.init_modif() - #self.valid = 1 - #self.state = 'unchanged' - def get_contexte_jdc(self,fichier,text): """ - Interprète text comme un texte de jdc et retourne le - contexte final - cad le dictionnaire des sd disponibles à la dernière étape + Interprète text comme un texte de jdc et retourne le contexte final. + + Le contexte final est le dictionnaire des sd disponibles à la dernière étape. Si text n'est pas un texte de jdc valide, retourne None + ou leve une exception --> utilisée par ops.POURSUITE et INCLUDE """ + #print "get_contexte_jdc",self,self.nom + # On recupere l'etape courante + step=CONTEXT.get_current_step() try: - # on essaie de créer un objet JDC... - context_ini = self.parent.get_contexte_avant(self) + # on essaie de créer un objet JDC auxiliaire avec un contexte initial + # Attention get_contexte_avant retourne un dictionnaire qui contient + # le contexte courant. Ce dictionnaire est reactualise regulierement. + # Si on veut garder l'etat du contexte fige, il faut en faire une copie. + context_ini = self.parent.get_contexte_avant(self).copy() + #print "get_contexte_jdc",context_ini.keys() + # Indispensable avant de creer un nouveau JDC CONTEXT.unset_current_step() - j=self.jdc.definition(procedure=text,cata=self.jdc.cata, - nom=fichier, - context_ini = context_ini, - appli=self.jdc.appli) + args=self.jdc.args + prefix_include=None + if hasattr(self,'prefix'): + prefix_include=self.prefix + # ATTENTION : le dictionnaire recorded_units sert à memoriser les unites des + # fichiers inclus. Il est preferable de garder le meme dictionnaire pendant + # tout le traitement et de ne pas le reinitialiser brutalement (utiliser + # clear plutot) si on ne veut pas perdre la memoire des unites. + # En principe si la memorisation est faite au bon moment il n'est pas necessaire + # de prendre cette precaution mais ce n'est pas vrai partout. + old_recorded_units=self.recorded_units.copy() + + # on supprime l'ancien jdc_aux s'il existe + if hasattr(self,'jdc_aux') and self.jdc_aux: + self.jdc_aux.supprime_aux() + + if fichier is None:fichier="SansNom" + + # Il faut convertir le texte inclus en fonction du format + # sauf les INCLUDE_MATERIAU + self.text_converted=0 + self.text_error="" + if self.nom != "INCLUDE_MATERIAU": + if self.parent.appli.ihm == "QT" : + format=self.parent.appli.appliEficas.format_fichier + else : + format=self.jdc.appli.format_fichier.get() + if convert.plugins.has_key(format): + # Le convertisseur existe on l'utilise + p=convert.plugins[format]() + p.text=text + text=p.convert('exec',self.jdc.appli) + #Si le fichier ne peut pas etre converti, le cr n'est pas vide + #et le texte est retourné tel que + if not p.cr.estvide(): + self.text_converted=0 + self.text_error=str(p.cr) + else: + self.text_converted=1 + + + j=self.JdC_aux( procedure=text, nom=fichier, + appli=self.jdc.appli, + cata=self.jdc.cata, + cata_ord_dico=self.jdc.cata_ordonne_dico, + context_ini = context_ini, + jdc_pere=self.jdc,etape_include=self, + prefix_include=prefix_include, + recorded_units=self.recorded_units, + old_recorded_units=old_recorded_units,**args) + j.analyse() + # On récupère les étapes internes (pour validation) + self.etapes=j.etapes + self.jdc_aux=j except: traceback.print_exc() + # On retablit l'etape courante step + CONTEXT.unset_current_step() + CONTEXT.set_current_step(step) return None - CONTEXT.set_current_step(self) + if not j.cr.estvide(): - raise Exception("Impossible de relire le fichier\n"+str(j.cr)) - - #XXX la validité d'un source inclus n'est pas identique à celle d'un JDC complet - # impossible de la tester en dehors du JDC d'accueil - #cr=j.report() - #if not cr.estvide(): - # raise Exception("Le fichier contient des erreurs\n"+str(j.cr)) - j_context=j.get_contexte_avant(None) - # XXX j.g_context doit donner le meme résultat - # On retourne le contexte apres la derniere etape - # XXX j.supprime() ??? - self.verif_contexte(j_context) - # Le contexte est acceptable. On récupère les étapes internes (pour validation) - self.etapes=j.etapes - return j_context + # Erreurs dans l'INCLUDE. On garde la memoire du fichier + # mais on n'insere pas les concepts + # On retablit l'etape courante step + #print j.cr + CONTEXT.unset_current_step() + CONTEXT.set_current_step(step) + raise Exception("Impossible de relire le fichier\n"+str(j.cr)) - def verif_contexte(self,context): - """ - On verifie que le contexte context peut etre inséré dans le jeu - de commandes à la position de self - """ - for nom_sd,sd in context.items(): - if not isinstance(sd,ASSD):continue - if self.parent.get_sd_apres_etape(nom_sd,etape=self): - # Il existe un concept apres self => impossible d'inserer - raise Exception("Impossible d'inclure le fichier. Un concept de nom " + - "%s existe déjà dans le jeu de commandes." % nom_sd) + if not j.isvalid(): + # L'INCLUDE n'est pas valide. + # on produit un rapport d'erreurs + cr=j.report() + #print cr + # On retablit l'etape courante step + CONTEXT.unset_current_step() + CONTEXT.set_current_step(step) + raise Exception("Le fichier include contient des erreurs\n"+str(cr)) + + # Si aucune erreur rencontrée + # On recupere le contexte de l'include verifie + try: + j_context=j.get_verif_contexte() + #print j_context.keys() + #print j.g_context.keys() + except: + # On retablit l'etape courante step + CONTEXT.unset_current_step() + CONTEXT.set_current_step(step) + raise + + # Si on est arrivé ici, le texte du fichier inclus (INCLUDE, POURSUITE, ...) + # est valide et insérable dans le JDC + + # On remplit le dictionnaire des concepts produits inclus + # en retirant les concepts présents dans le contexte initial + # On ajoute egalement le concept produit dans le sds_dict du parent + # sans verification car on est sur (verification integrée) que + # le nommage est possible + self.g_context.clear() + for k,v in j_context.items(): + if not context_ini.has_key(k) or context_ini[k] != v: + self.g_context[k]=v + self.parent.sds_dict[k]=v + + #Ce traitement n'est réalisé que dans les cas suivants: + # - si convert n'a pas pu convertir le jeu de commandes + # - et ce n'est pas un INCLUDE_MATERIAU + #On collecte les variables Python qui ne sont pas dans le contexte initial + #et dans le contexte validé et on en fait un pseudo-parametre (Variable) + if self.text_converted == 0 and self.nom != "INCLUDE_MATERIAU": + for k,v in j.g_context.items(): + if k in context_ini:continue + if k in j_context:continue + if isinstance(v,ASSD):continue + if isinstance(v,I_ENTITE.ENTITE):continue + if isinstance(v,I_OBJECT.OBJECT):continue + if callable(v):continue + self.g_context[k]=param2.Variable(k,v) + + # On recupere le contexte courant + self.current_context=j.current_context + self.index_etape_courante=j.index_etape_courante + self.jdc_aux=j + + # On retablit l'etape courante step + CONTEXT.unset_current_step() + CONTEXT.set_current_step(step) + + return j_context def reevalue_sd_jdc(self): """ Avec la liste des SD qui ont été supprimées, propage la - disparition de ces SD dans totues les étapes et descendants + disparition de ces SD dans toutes les étapes et descendants """ - l_sd = self.diff_contextes() - if len(l_sd) == 0 : return - for sd in l_sd: - self.jdc.delete_concept(sd) + #print "reevalue_sd_jdc" + l_sd_supp,l_sd_repl = self.diff_contextes() + for sd in l_sd_supp: + self.parent.delete_concept_after_etape(self,sd) + for old_sd,sd in l_sd_repl: + self.parent.replace_concept_after_etape(self,old_sd,sd) def diff_contextes(self): """ Réalise la différence entre les 2 contextes old_contexte_fichier_init et contexte_fichier_init - cad retourne la liste des sd qui ont disparu + cad retourne la liste des sd qui ont disparu ou ne derivent pas + de la meme classe et des sd qui ont ete remplacees """ - if not hasattr(self,'old_contexte_fichier_init'):return [] + if not hasattr(self,'old_contexte_fichier_init'):return [],[] l_sd_suppressed = [] + l_sd_replaced = [] for old_key in self.old_contexte_fichier_init.keys(): if not self.contexte_fichier_init.has_key(old_key): if isinstance(self.old_contexte_fichier_init[old_key],ASSD): l_sd_suppressed.append(self.old_contexte_fichier_init[old_key]) - return l_sd_suppressed + else: + if isinstance(self.old_contexte_fichier_init[old_key],ASSD): + # Un concept de meme nom existe + old_class=self.old_contexte_fichier_init[old_key].__class__ + if not isinstance(self.contexte_fichier_init[old_key],old_class): + # S'il n'est pas d'une classe derivee, on le supprime + l_sd_suppressed.append(self.old_contexte_fichier_init[old_key]) + else: + l_sd_replaced.append((self.old_contexte_fichier_init[old_key],self.contexte_fichier_init[old_key])) + return l_sd_suppressed,l_sd_replaced + def control_sdprods(self,d): + """ + Cette methode doit verifier que les concepts produits par la + commande ne sont pas incompatibles avec le contexte fourni (d). + Si c'est le cas, le concept produit doit etre supprime + Si la macro a elle meme des etapes, elle doit propager + le traitement (voir methode control_jdc_context_apres de I_JDC) + """ + #print "I_MACRO_ETAPE.control_sdprods",d.keys(),self.nom,self.sd and self.sd.nom + if self.sd: + if d.has_key(self.sd.nom): + # Le concept est deja defini + if self.reuse and self.reuse is d[self.sd.nom]: + # Le concept est reutilise : situation normale + pass + else: + # Redefinition du concept, on l'annule + #XXX on pourrait simplement annuler son nom pour conserver les objets + # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??) + self.init_modif() + sd=self.sd + self.sd=self.reuse=self.sdnom=None + self.parent.delete_concept_after_etape(self,sd) + self.fin_modif() + + # On verifie les concepts a droite du signe = + self.init_modif() + sdprods=self.sdprods[:] + self.sdprods=[] + for co in sdprods: + if d.has_key(co.nom) and co is not d[co.nom] : + #nettoie les mots cles de l'étape qui ont comme valeur co + self.delete_concept(co) + #supprime les references a co dans les etapes suivantes + self.parent.delete_concept_after_etape(self,co) + else: + self.sdprods.append(co) + self.fin_modif() + + for e in self.etapes: + e.control_sdprods(d) + e.update_context(d) + + def supprime_sdprod(self,sd): + """ + Supprime le concept produit sd s'il est produit par l'etape + """ + if sd in self.sdprods: + self.init_modif() + self.parent.del_sdprod(sd) + self.sdprods.remove(sd) + self.fin_modif() + self.parent.delete_concept(sd) + return + + if sd is not self.sd :return + if self.sd is not None : + self.init_modif() + self.parent.del_sdprod(sd) + self.sd=None + self.fin_modif() + self.parent.delete_concept(sd) + def supprime_sdprods(self): """ - Fonction: - Lors d'une destruction d'etape, detruit tous les concepts produits - Un opérateur n a qu un concept produit - Une procedure n'en a aucun - Une macro en a en général plus d'un + Fonction: Lors de la destruction de la macro-etape, detruit tous les concepts produits + Un opérateur n a qu un concept produit + Une procedure n'en a aucun + Une macro en a en général plus d'un """ - if not self.is_reentrant() : + #print "supprime_sdprods" + if self.reuse is not self.sd : # l'étape n'est pas réentrante # le concept retourné par l'étape est à supprimer car il était # créé par l'étape @@ -140,9 +342,701 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): # Si la macro a des etapes et des concepts inclus, on les detruit for nom_sd,co in self.g_context.items(): if not isinstance(co,ASSD):continue - print "Delete: ",self.nom,co.nom self.parent.del_sdprod(co) self.parent.delete_concept(co) # On met g_context à blanc self.g_context={} + + def close(self): + #print "close",self + if hasattr(self,"jdc_aux") and self.jdc_aux: + # La macro a un jdc auxiliaire inclus. On demande sa fermeture + self.jdc_aux.close() + + def reset_context(self): + if hasattr(self,"jdc_aux") and self.jdc_aux: + # La macro a un jdc auxiliaire inclus. On demande la reinitialisation du contexte + self.jdc_aux.reset_context() + + def update_concept(self,sd): + I_ETAPE.ETAPE.update_concept(self,sd) + for etape in self.etapes: + etape.update_concept(sd) + + def delete_concept(self,sd): + """ + Fonction : Mettre a jour les mots cles de l etape et eventuellement + le concept produit si reuse suite à la disparition du concept sd + Seuls les mots cles simples MCSIMP font un traitement autre + que de transmettre aux fils + """ + #print "delete_concept",sd + I_ETAPE.ETAPE.delete_concept(self,sd) + for etape in self.etapes: + etape.delete_concept(sd) + + def replace_concept(self,old_sd,sd): + """ + Fonction : Mettre a jour les mots cles de l etape et le concept produit si reuse + suite au remplacement du concept old_sd par sd + """ + #print "replace_concept",old_sd,sd + I_ETAPE.ETAPE.replace_concept(self,old_sd,sd) + for etape in self.etapes: + etape.replace_concept(old_sd,sd) + def change_fichier_init(self,new_fic,text): + """ + Tente de changer le fichier include. Le precedent include est conservé + dans old_xxx + """ + #print "change_fichier_init",new_fic + if not hasattr(self,'fichier_ini'): + self.fichier_ini=None + self.fichier_text=None + self.fichier_err="Le fichier n'est pas defini" + self.contexte_fichier_init={} + self.recorded_units={} + self.jdc_aux=None + self.fichier_unite="PasDefini" + import Extensions.jdc_include + self.JdC_aux=Extensions.jdc_include.JdC_include + + self.old_fic = self.fichier_ini + self.old_text = self.fichier_text + self.old_err = self.fichier_err + self.old_context=self.contexte_fichier_init + self.old_units=self.recorded_units + self.old_etapes=self.etapes + self.old_jdc_aux=self.jdc_aux + + self.fichier_ini = new_fic + self.fichier_text=text + + try: + self.make_contexte_include(new_fic,text) + except: + l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) + self.fichier_err=string.join(l) + raise + + # L'evaluation de text dans un JDC auxiliaire s'est bien passé + # on peut poursuivre le traitement + self.init_modif() + self.state="undetermined" + self.fichier_err=None + # On enregistre la modification de fichier + self.record_unite() + # Le contexte du parent doit etre reinitialise car les concepts produits ont changé + self.parent.reset_context() + + # Si des concepts ont disparu lors du changement de fichier, on demande leur suppression + self.old_contexte_fichier_init=self.old_context + self.reevalue_sd_jdc() + + self.fin_modif() + if self.old_jdc_aux: + self.old_jdc_aux.close() + + def restore_fichier_init(self): + """ + Restaure le fichier init enregistre dans old_xxx + """ + self.fichier_ini=self.old_fic + self.fichier_text=self.old_text + self.fichier_err=self.old_err + self.contexte_fichier_init=self.old_context + self.recorded_units=self.old_units + self.etapes=self.old_etapes + self.jdc_aux=self.old_jdc_aux + + def force_fichier_init(self): + """ + Force le remplacement du fichier init meme si le remplacant est en erreur + """ + # Reinitialisation complete du compte-rendu d'erreurs + self.jdc_aux.cr=self.jdc_aux.CR() + # On remplit le dictionnaire des concepts produits inclus + # en retirant les concepts présents dans le contexte initial + # On ajoute egalement le concept produit dans le sds_dict du parent + # sans verification car on est sur (verification integrée) que + # le nommage est possible + j_context=self.jdc_aux.get_contexte_avant(None) + self.g_context.clear() + context_ini=self.jdc_aux.context_ini + for k,v in j_context.items(): + if not context_ini.has_key(k) or context_ini[k] != v: + self.g_context[k]=v + self.parent.sds_dict[k]=v + # On recupere le contexte courant + self.current_context=self.jdc_aux.current_context + self.index_etape_courante=self.jdc_aux.index_etape_courante + self.contexte_fichier_init = j_context + self.fichier_err = None + + # On enregistre la modification de fichier + self.init_modif() + self.state="undetermined" + self.record_unite() + # Le contexte du parent doit etre reinitialise car les concepts produits ont changé + self.parent.reset_context() + + # On remplace les anciens concepts par les nouveaux (y compris ajouts + # et suppression) et on propage les modifications aux etapes precedentes et suivantes + # reevalue_sd_jdc construit la liste des differences entre les contextes contexte_fichier_init + # et old_contexte_fichier_init et effectue les destructions et remplacements de concept + # necessaires + self.old_contexte_fichier_init=self.old_context + self.reevalue_sd_jdc() + self.fin_modif() + if self.old_jdc_aux: + self.old_jdc_aux.close() + + self.jdc_aux.force_contexte(self.g_context) + + def build_include(self,fichier,text): + import Extensions.jdc_include + self.JdC_aux=Extensions.jdc_include.JdC_include + # un include partage la table des unites avec son parent (jdc) + self.recorded_units=self.parent.recorded_units + self.build_jdcaux(fichier,text) + + def build_poursuite(self,fichier,text): + import Extensions.jdc_include + self.JdC_aux=Extensions.jdc_include.JdC_poursuite + # une poursuite a sa propre table d'unites + self.recorded_units={} + self.build_jdcaux(fichier,text) + + def build_jdcaux(self,fichier,text): + """ + Cree un jdc auxiliaire initialise avec text. + Initialise le nom du fichier associé avec fichier + N'enregistre pas d'association unite <-> fichier + """ + self.fichier_ini = fichier + self.fichier_text= text + self.fichier_unite=None + self.fichier_err = None + try: + contexte = self.get_contexte_jdc(fichier,text) + if contexte is None : + # Impossible de construire le jdc auxiliaire (sortie par None) + # On simule une sortie par exception + raise Exception("Impossible de construire le jeu de commandes correspondant au fichier") + else: + # La construction du jdc auxiliaire est allée au bout + self.contexte_fichier_init = contexte + self.init_modif() + self.fin_modif() + except: + # Impossible de construire le jdc auxiliaire (sortie par exception) + l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) + if self.jdc.appli: + self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus", + message="Ce fichier ne sera pas pris en compte\n"+string.join(l) + ) + self.g_context={} + self.etapes=[] + self.jdc_aux=None + self.fichier_err = string.join(l) + self.contexte_fichier_init={} + self.init_modif() + self.fin_modif() + raise + + def make_contexte_include(self,fichier,text): + """ + Cette méthode sert à créer un contexte en interprétant un texte source Python. + """ + #print "make_contexte_include",fichier + # on récupère le contexte d'un nouveau jdc dans lequel on interprete text + contexte = self.get_contexte_jdc(fichier,text) + if contexte == None : + raise Exception("Impossible de construire le jeu de commandes correspondant au fichier") + else: + # Pour les macros de type include : INCLUDE, INCLUDE_MATERIAU et POURSUITE + # l'attribut g_context est un dictionnaire qui contient les concepts produits par inclusion + # l'attribut contexte_fichier_init est un dictionnaire qui contient les concepts produits + # en sortie de macro. g_context est obtenu en retirant de contexte_fichier_init les concepts + # existants en debut de macro contenus dans context_ini (dans get_contexte_jdc) + # g_context est utilisé pour avoir les concepts produits par la macro + # contexte_fichier_init est utilisé pour avoir les concepts supprimés par la macro + self.contexte_fichier_init = contexte + + def reevalue_fichier_init_OBSOLETE(self): + """Recalcule les concepts produits par le fichier enregistre""" + #print "reevalue_fichier_init" + old_context=self.contexte_fichier_init + try: + self.make_contexte_include(self.fichier_ini ,self.fichier_text) + except: + l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) + self.fichier_err = string.join(l) + self.g_context={} + self.etapes=[] + self.jdc_aux=None + self.old_contexte_fichier_init=old_context + self.contexte_fichier_init={} + self.reevalue_sd_jdc() + return + + # L'evaluation s'est bien passee + self.fichier_err = None + self.old_contexte_fichier_init=old_context + self.reevalue_sd_jdc() + + def update_fichier_init(self,unite): + """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur + les noms des fichiers + Ceci suppose que les relations entre unites et noms ont été memorisees préalablement + L'include a été initialisé précédemment. Le jdc auxiliaire existe. + """ + #print "update_fichier_init",unite,self.fichier_unite + self.old_contexte_fichier_init=self.contexte_fichier_init + old_fichier_ini=self.fichier_ini + if not hasattr(self,"jdc_aux"):self.jdc_aux=None + old_jdc_aux=self.jdc_aux + + #print "update_fichier_init",self,self.parent,self.parent.recorded_units + + if self.fichier_unite is None: + # L'unité n'était pas définie précédemment. On ne change que l'unite + #print "update_fichier_init","pas de changement dans include" + self.fichier_unite=unite + return + elif unite == self.fichier_unite : + # L'unité n'a pas changé + #print "update_fichier_init","pas de changement dans include 3" + return + elif unite != self.fichier_unite : + # L'unité était définie précédemment. On remplace l'include + # + f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom) + if f is None: + # Le fichier associé n'a pas pu etre defini + # on change l'unite associée mais pas l'include + #print "update_fichier_init","pas de changement dans include 2" + self.fichier_unite=unite + return + else: + self.fichier_ini = f + self.fichier_text=text + self.fichier_unite=unite + #print "update_fichier_init",self.recorded_units + + #print "update_fichier_init",self.fichier_ini,self.fichier_text,self.fichier_unite + + if old_fichier_ini == self.fichier_ini: + # Le fichier inclus n'a pas changé. On ne recrée pas le contexte + # mais on enregistre le changement d'association unite <-> fichier + #print "update_fichier_init.fichier inchange",self.jdc_aux.context_ini + self.parent.record_unit(unite,self) + return + + try: + self.fichier_err=None + self.make_contexte_include(self.fichier_ini,self.fichier_text) + # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects + # avant d'appeler change_unit + except: + # Erreurs lors de l'evaluation de text dans un JDC auxiliaire + l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) + # On conserve la memoire du nouveau fichier + # mais on n'utilise pas les concepts crees par ce fichier + # on met l'etape en erreur : fichier_err=string.join(l) + self.fichier_err=string.join(l) + self.g_context={} + self.etapes=[] + self.jdc_aux=None + self.contexte_fichier_init={} + + if old_jdc_aux: + old_jdc_aux.close() + self.parent.record_unit(unite,self) + # Le contexte du parent doit etre reinitialise car les concepts + # produits ont changé + self.parent.reset_context() + # Si des concepts ont disparu lors du changement de fichier, on + # demande leur suppression + self.reevalue_sd_jdc() + #print "update_fichier_init",self.jdc_aux.context_ini.keys() + + def record_unite(self): + #print "record_unite",self.nom + if self.nom == "POURSUITE": + self.parent.record_unit(None,self) + else: + if hasattr(self,'fichier_unite') : + self.parent.record_unit(self.fichier_unite,self) + + def get_file_memo(self,unite=None,fic_origine=''): + """Retourne le nom du fichier et le source correspondant a l'unite unite + Initialise en plus recorded_units + """ + #print "get_file_memo",unite,fic_origine,self,self.parent + #print self.parent.recorded_units + if unite is None: + # On est dans le cas d'une poursuite. On ne reutilise aucune unite de parent + units={} + else: + # On est dans le cas d'un include. On reutilise toutes les unites de parent + units=self.parent.recorded_units + + if self.parent.recorded_units.has_key(unite): + f,text,units=self.parent.recorded_units[unite] + elif self.jdc : + f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine) + else: + f,text=None,None + + self.recorded_units=units + if f is None and self.jdc.appli: + self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus", + message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini") + return f,text + + def update_context(self,d): + """ + Met à jour le contexte contenu dans le dictionnaire d + Une MACRO_ETAPE peut ajouter plusieurs concepts dans le contexte + Une fonction enregistree dans op_init peut egalement modifier le contexte + """ + #print "update_context",self,self.nom,d.keys() + if hasattr(self,"jdc_aux") and self.jdc_aux: + #ATTENTION: update_context NE DOIT PAS appeler reset_context + # car il appelle directement ou indirectement update_context + # equivalent a reset_context. Evite les recursions + self.jdc_aux.context_ini=d.copy() + self.jdc_aux.current_context={} + self.jdc_aux.index_etape_courante=0 + #ATTENTION: il ne faut pas utiliser self.jdc_aux.get_contexte_avant + #car cet appel conduit a des remontées multiples incohérentes dans le + # ou les parents. + #get_context_avant appelle update_context qui NE DOIT PAS appeler get_contexte_avant + #On n'a besoin que d'un update local connaissant + # le contexte amont : d qui sert a reinitialiser self.context_ini + for e in self.etapes: + e.update_context(d) + return + + if type(self.definition.op_init) == types.FunctionType: + apply(self.definition.op_init,(self,d)) + if self.sd != None:d[self.sd.nom]=self.sd + for co in self.sdprods: + d[co.nom]=co + #print "update_context.fin",d.keys() + +#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro) + def copy(self): + etape=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.copy(self) + if hasattr(etape,"etapes") :etape.etapes=[] + if hasattr(etape,"jdc_aux") : + etape.jdc_aux=None + del etape.fichier_ini + return etape + + def supprime(self): + #print "supprime",self + if hasattr(self,"jdc_aux") and self.jdc_aux: + self.jdc_aux.supprime_aux() + self.jdc_aux=None + Noyau.N_MACRO_ETAPE.MACRO_ETAPE.supprime(self) + # self.contexte_fichier_init={} + # self.old_contexte_fichier_init={} + # self.g_context={} + # self.current_context={} + # self.etapes=[] + # self.mc_liste=[] + +#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro) + def get_file(self,unite=None,fic_origine=''): + """Retourne le nom du fichier et le source correspondant a l'unite unite + """ + if self.jdc : + f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine) + else: + f,text=None,None + return f,text + + + def make_include2(self,fichier=None): + # gestion de l unicite SVP + unite=999 + if hasattr(self,'fichier_ini') : return + #print "je passe le if" + if fichier == None : + fichier=str(self.jdc.appli.get_file_variable()) + #print fichier + if fichier == str("") : + self.fichier_ini="badfile" + self.fichier_text="" + self.fichier_err="Le fichier INCLUDE n est pas defini" + self.parent.record_unit(999,self) + try : + MCFils=self.get_child('FileName') + MCFils.set_valeur(None) + except : + pass + raise Exception(self.fichier_err) + + # On memorise le fichier retourne + self.fichier_ini = fichier + self.fichier_text = "" + self.contexte_fichier_init={} + self.fichier_unite=999 + self.fichier_err=None + try : + from openturns import WrapperFile + monWrapper=WrapperFile(fichier) + data=monWrapper.getWrapperData() + maVariableListe=data.getVariableList() + nbVariables=maVariableListe.getSize() + for i in range(nbVariables) : + nom=maVariableListe[i].id_ + type=maVariableListe[i].type_ + if type : + ligneTexte="%s=DETERMINISTICVARIABLE(N='%s',T='in',R=%d);\n" % (nom, nom, i) + else : + ligneTexte="%s=DETERMINISTICVARIABLE(N='%s',T='out',R=%d);\n" % (nom, nom, i) + self.fichier_text = self.fichier_text + ligneTexte + except: + self.make_incl2_except() + raise + + try: + import Extensions.jdc_include + except: + traceback.print_exc() + self.make_incl2_except() + raise + self.JdC_aux=Extensions.jdc_include.JdC_include + + try: + self.make_contexte_include(self.fichier_ini ,self.fichier_text) + self.parent.record_unit(unite,self) + try : + MCFils=self.get_child('FileName') + MCFils.set_valeur(fichier) + except : + pass + except: + self.make_incl2_except() + raise + + def make_incl2_except(self): + #print "make_incl2_except" + l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) + if self.jdc.appli: + self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus", + message="Le contenu de ce fichier ne sera pas pris en compte\n"+string.join(l) + ) + self.parent.record_unit(unite,self) + self.g_context={} + self.etapes=[] + self.jdc_aux=None + self.fichier_err = string.join(l) + self.contexte_fichier_init={} + try : + MCFils=self.get_child('FileName') + MCFils.set_valeur(None) + except : + pass + + +#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro) + def make_include(self,unite=None): + """ + Inclut un fichier dont l'unite logique est unite + Cette methode est appelee par la fonction sd_prod de la macro INCLUDE + Si l'INCLUDE est invalide, la methode doit produire une exception + Sinon on retourne None. Les concepts produits par l'INCLUDE sont + pris en compte par le JDC parent lors du calcul du contexte (appel de ???) + """ + #print "make_include",unite + # On supprime l'attribut unite qui bloque l'evaluation du source de l'INCLUDE + # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini + # Si unite n'a pas de valeur, l'etape est forcement invalide. On peut retourner None + if not unite : return + + if not hasattr(self,'fichier_ini') : + # Si le fichier n'est pas defini on le demande + f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom) + # On memorise le fichier retourne + self.fichier_ini = f + self.fichier_text = text + self.contexte_fichier_init={} + self.fichier_unite=unite + self.fichier_err=None + try: + import Extensions.jdc_include + except: + traceback.print_exc() + raise + self.JdC_aux=Extensions.jdc_include.JdC_include + + #print "make_include",self.fichier_ini,self.fichier_text + if f is None and not text: + self.fichier_err="Le fichier INCLUDE n est pas defini" + self.parent.record_unit(unite,self) + raise Exception(self.fichier_err) + + try: + self.make_contexte_include(self.fichier_ini ,self.fichier_text) + self.parent.record_unit(unite,self) + except: + l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) + if self.jdc.appli: + self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus", + message="Le contenu de ce fichier ne sera pas pris en compte\n"+string.join(l) + ) + self.parent.record_unit(unite,self) + self.g_context={} + self.etapes=[] + self.jdc_aux=None + self.fichier_err = string.join(l) + self.contexte_fichier_init={} + raise + + else: + # Si le fichier est deja defini on ne reevalue pas le fichier + # et on leve une exception si une erreur a été enregistrée + self.update_fichier_init(unite) + self.fichier_unite=unite + if self.fichier_err is not None: raise Exception(self.fichier_err) + + +#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro) + def make_contexte(self,fichier,text): + """ + Cette méthode sert à créer un contexte pour INCLUDE_MATERIAU + en interprétant un texte source Python + Elle est appelee par la fonction sd_prod d'INCLUDE_MATERIAU + """ + #print "make_contexte",fichier + # On supprime l'attribut mat qui bloque l'evaluation du source de l'INCLUDE_MATERIAU + # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini + if hasattr(self,'mat'):del self.mat + if not hasattr(self,'fichier_ini') or self.fichier_ini != fichier or self.fichier_mater != self.nom_mater: + # le fichier est nouveau ou change + self.fichier_ini =fichier + self.fichier_unite =fichier + self.fichier_mater=self.nom_mater + self.fichier_text=text + self.fichier_err=None + self.contexte_fichier_init={} + # On specifie la classe a utiliser pour le JDC auxiliaire + try: + import Extensions.jdc_include + self.JdC_aux=Extensions.jdc_include.JdC_include + except: + raise + try: + self.make_contexte_include(self.fichier_ini ,self.fichier_text) + if not self.g_context.has_key(self.nom_mater): + #Pour permettre de lire un jeu de commandes avec des INCLUDE_MATERIAU errones + self.g_context[self.nom_mater]=None + if self.parent: self.parent.g_context[self.nom_mater]=None + except: + l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) + self.fichier_err = string.join(l) + self.g_context={} + #Pour permettre de lire un jeu de commandes avec des INCLUDE_MATERIAU errones + if self.parent: + self.parent.g_context[self.nom_mater]=None + self.g_context[self.nom_mater]=None + #------------- + self.etapes=[] + self.jdc_aux=None + self.contexte_fichier_init={} + raise + else: + # le fichier est le meme on ne le reevalue pas + # et on leve une exception si une erreur a été enregistrée + if self.fichier_err is not None: raise Exception(self.fichier_err) + +#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro) + def update_sdprod(self,cr='non'): + # Cette methode peut etre appelee dans EFICAS avec des mots cles de + # la commande modifies. Ceci peut conduire a la construction ou + # a la reconstruction d'etapes dans le cas d'INCLUDE ou d'INCLUDE_MATERIAU + # Il faut donc positionner le current_step avant l'appel + CONTEXT.unset_current_step() + CONTEXT.set_current_step(self) + valid=Validation.V_MACRO_ETAPE.MACRO_ETAPE.update_sdprod(self,cr=cr) + CONTEXT.unset_current_step() + return valid + +#ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro + def Build_sd(self,nom): + """ + Methode de Noyau surchargee pour poursuivre malgre tout + si une erreur se produit pendant la creation du concept produit + """ + try: + sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom) + except AsException,e: + # Une erreur s'est produite lors de la construction du concept + # Comme on est dans EFICAS, on essaie de poursuivre quand meme + # Si on poursuit, on a le choix entre deux possibilités : + # 1. on annule la sd associée à self + # 2. on la conserve mais il faut la retourner + # On choisit de l'annuler + # En plus il faut rendre coherents sdnom et sd.nom + self.sd=None + self.sdnom=None + self.state="unchanged" + self.valid=0 + + return self.sd + +#ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro + def make_poursuite(self): + """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE + """ + #print "make_poursuite" + if not hasattr(self,'fichier_ini') : + # Si le fichier n'est pas defini on le demande + f,text=self.get_file_memo(fic_origine=self.parent.nom) + # On memorise le fichier retourne + self.fichier_ini = f + self.fichier_unite = None + self.fichier_text = text + self.fichier_err=None + try: + import Extensions.jdc_include + except: + traceback.print_exc() + raise + self.JdC_aux=Extensions.jdc_include.JdC_poursuite + self.contexte_fichier_init={} + #print "make_poursuite",self.fichier_ini,self.fichier_text + + if f is None: + self.fichier_err="Le fichier POURSUITE n'est pas defini" + self.jdc_aux=None + self.parent.record_unit(None,self) + raise Exception(self.fichier_err) + + try: + self.make_contexte_include(self.fichier_ini,self.fichier_text) + self.parent.record_unit(None,self) + except: + l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) + if self.jdc.appli: + self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier poursuite", + message="Ce fichier ne sera pas pris en compte\n"+string.join(l) + ) + self.parent.record_unit(None,self) + self.g_context={} + self.etapes=[] + self.jdc_aux=None + self.fichier_err = string.join(l) + self.contexte_fichier_init={} + raise + + else: + # Si le fichier est deja defini on ne reevalue pas le fichier + # et on leve une exception si une erreur a été enregistrée + self.update_fichier_init(None) + if self.fichier_err is not None: raise Exception(self.fichier_err)