1 # -*- coding: utf-8 -*-
2 # CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
20 # ======================================================================
25 import traceback,types,string
32 from Noyau.N_ASSD import ASSD
33 from Noyau import N__F
35 from Extensions import param2
37 # import rajoutés suite à l'ajout de Build_sd --> à résorber
38 import Noyau, Validation.V_MACRO_ETAPE
39 from Noyau import N_Exception
40 from Noyau.N_Exception import AsException
41 import Accas # attention aux imports circulaires
42 # fin import à résorber
44 class MACRO_ETAPE(I_ETAPE.ETAPE):
48 #indique si le jeu de commande inclus a pu etre analysé par convert
49 #pour etre editable (0=NON, 1=OUI)
52 self.recorded_units={}
54 def get_sdprods(self,nom_sd):
56 Fonction : retourne le concept produit par l etape de nom nom_sd
57 s il existe sinon None
59 if self.sd and self.sd.nom == nom_sd :return self.sd
60 for co in self.sdprods:
61 if co.nom == nom_sd:return co
62 if type(self.definition.op_init) == types.FunctionType:
64 apply(self.definition.op_init,(self,d))
65 return d.get(nom_sd,None)
68 def get_contexte_jdc(self,fichier,text):
70 Interprète text comme un texte de jdc et retourne le contexte final.
72 Le contexte final est le dictionnaire des sd disponibles à la dernière étape.
73 Si text n'est pas un texte de jdc valide, retourne None
75 --> utilisée par ops.POURSUITE et INCLUDE
77 #print "get_contexte_jdc",self,self.nom
78 # On recupere l'etape courante
79 step=CONTEXT.get_current_step()
81 # on essaie de créer un objet JDC auxiliaire avec un contexte initial
82 # Attention get_contexte_avant retourne un dictionnaire qui contient
83 # le contexte courant. Ce dictionnaire est reactualise regulierement.
84 # Si on veut garder l'etat du contexte fige, il faut en faire une copie.
85 context_ini = self.parent.get_contexte_avant(self).copy()
86 #print "get_contexte_jdc",context_ini.keys()
88 # Indispensable avant de creer un nouveau JDC
89 CONTEXT.unset_current_step()
92 if hasattr(self,'prefix'):
93 prefix_include=self.prefix
94 # ATTENTION : le dictionnaire recorded_units sert à memoriser les unites des
95 # fichiers inclus. Il est preferable de garder le meme dictionnaire pendant
96 # tout le traitement et de ne pas le reinitialiser brutalement (utiliser
97 # clear plutot) si on ne veut pas perdre la memoire des unites.
98 # En principe si la memorisation est faite au bon moment il n'est pas necessaire
99 # de prendre cette precaution mais ce n'est pas vrai partout.
100 old_recorded_units=self.recorded_units.copy()
102 # on supprime l'ancien jdc_aux s'il existe
103 if hasattr(self,'jdc_aux') and self.jdc_aux:
104 self.jdc_aux.supprime_aux()
106 if fichier is None:fichier="SansNom"
108 # Il faut convertir le texte inclus en fonction du format
109 # sauf les INCLUDE_MATERIAU
110 self.text_converted=0
112 if self.nom != "INCLUDE_MATERIAU":
113 if self.parent.appli.ihm == "QT" :
114 format=self.jdc.appli.format_fichier
116 format=self.jdc.appli.format_fichier.get()
117 if convert.plugins.has_key(format):
118 # Le convertisseur existe on l'utilise
119 p=convert.plugins[format]()
121 text=p.convert('exec',self.jdc.appli)
122 #Si le fichier ne peut pas etre converti, le cr n'est pas vide
123 #et le texte est retourné tel que
124 if not p.cr.estvide():
125 self.text_converted=0
126 self.text_error=str(p.cr)
128 self.text_converted=1
130 j=self.JdC_aux( procedure=text, nom=fichier,
131 appli=self.jdc.appli,
133 cata_ord_dico=self.jdc.cata_ordonne_dico,
134 context_ini = context_ini,
135 jdc_pere=self.jdc,etape_include=self,
136 prefix_include=prefix_include,
137 recorded_units=self.recorded_units,
138 old_recorded_units=old_recorded_units,**args)
141 # On récupère les étapes internes (pour validation)
145 traceback.print_exc()
146 # On retablit l'etape courante step
147 CONTEXT.unset_current_step()
148 CONTEXT.set_current_step(step)
151 if not j.cr.estvide():
152 # Erreurs dans l'INCLUDE. On garde la memoire du fichier
153 # mais on n'insere pas les concepts
154 # On retablit l'etape courante step
156 CONTEXT.unset_current_step()
157 CONTEXT.set_current_step(step)
158 raise Exception("Impossible de relire le fichier\n"+str(j.cr))
161 # L'INCLUDE n'est pas valide.
162 # on produit un rapport d'erreurs
165 # On retablit l'etape courante step
166 CONTEXT.unset_current_step()
167 CONTEXT.set_current_step(step)
168 raise Exception("Le fichier include contient des erreurs\n"+str(cr))
170 # Si aucune erreur rencontrée
171 # On recupere le contexte de l'include verifie
173 j_context=j.get_verif_contexte()
174 #print j_context.keys()
175 #print j.g_context.keys()
177 # On retablit l'etape courante step
178 CONTEXT.unset_current_step()
179 CONTEXT.set_current_step(step)
182 # Si on est arrivé ici, le texte du fichier inclus (INCLUDE, POURSUITE, ...)
183 # est valide et insérable dans le JDC
185 # On remplit le dictionnaire des concepts produits inclus
186 # en retirant les concepts présents dans le contexte initial
187 # On ajoute egalement le concept produit dans le sds_dict du parent
188 # sans verification car on est sur (verification integrée) que
189 # le nommage est possible
190 self.g_context.clear()
191 for k,v in j_context.items():
192 if not context_ini.has_key(k) or context_ini[k] != v:
194 self.parent.sds_dict[k]=v
196 #Ce traitement n'est réalisé que dans les cas suivants:
197 # - si convert n'a pas pu convertir le jeu de commandes
198 # - et ce n'est pas un INCLUDE_MATERIAU
199 #On collecte les variables Python qui ne sont pas dans le contexte initial
200 #et dans le contexte validé et on en fait un pseudo-parametre (Variable)
201 if self.text_converted == 0 and self.nom != "INCLUDE_MATERIAU":
202 for k,v in j.g_context.items():
203 if k in context_ini:continue
204 if k in j_context:continue
205 if isinstance(v,ASSD):continue
206 if isinstance(v,I_ENTITE.ENTITE):continue
207 if isinstance(v,I_OBJECT.OBJECT):continue
208 if callable(v):continue
209 self.g_context[k]=param2.Variable(k,v)
211 # On recupere le contexte courant
212 self.current_context=j.current_context
213 self.index_etape_courante=j.index_etape_courante
216 # On retablit l'etape courante step
217 CONTEXT.unset_current_step()
218 CONTEXT.set_current_step(step)
222 def reevalue_sd_jdc(self):
224 Avec la liste des SD qui ont été supprimées, propage la
225 disparition de ces SD dans toutes les étapes et descendants
227 #print "reevalue_sd_jdc"
228 l_sd_supp,l_sd_repl = self.diff_contextes()
230 self.parent.delete_concept_after_etape(self,sd)
231 for old_sd,sd in l_sd_repl:
232 self.parent.replace_concept_after_etape(self,old_sd,sd)
234 def diff_contextes(self):
236 Réalise la différence entre les 2 contextes
237 old_contexte_fichier_init et contexte_fichier_init
238 cad retourne la liste des sd qui ont disparu ou ne derivent pas
239 de la meme classe et des sd qui ont ete remplacees
241 if not hasattr(self,'old_contexte_fichier_init'):return [],[]
244 for old_key in self.old_contexte_fichier_init.keys():
245 if not self.contexte_fichier_init.has_key(old_key):
246 if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
247 l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
249 if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
250 # Un concept de meme nom existe
251 old_class=self.old_contexte_fichier_init[old_key].__class__
252 if not isinstance(self.contexte_fichier_init[old_key],old_class):
253 # S'il n'est pas d'une classe derivee, on le supprime
254 l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
256 l_sd_replaced.append((self.old_contexte_fichier_init[old_key],self.contexte_fichier_init[old_key]))
257 return l_sd_suppressed,l_sd_replaced
259 def control_sdprods(self,d):
261 Cette methode doit verifier que les concepts produits par la
262 commande ne sont pas incompatibles avec le contexte fourni (d).
263 Si c'est le cas, le concept produit doit etre supprime
264 Si la macro a elle meme des etapes, elle doit propager
265 le traitement (voir methode control_jdc_context_apres de I_JDC)
267 #print "I_MACRO_ETAPE.control_sdprods",d.keys(),self.nom,self.sd and self.sd.nom
269 if d.has_key(self.sd.nom):
270 # Le concept est deja defini
271 if self.reuse and self.reuse is d[self.sd.nom]:
272 # Le concept est reutilise : situation normale
275 # Redefinition du concept, on l'annule
276 #XXX on pourrait simplement annuler son nom pour conserver les objets
277 # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
280 self.sd=self.reuse=self.sdnom=None
281 self.parent.delete_concept_after_etape(self,sd)
284 # On verifie les concepts a droite du signe =
286 sdprods=self.sdprods[:]
289 if d.has_key(co.nom) and co is not d[co.nom] :
290 #nettoie les mots cles de l'étape qui ont comme valeur co
291 self.delete_concept(co)
292 #supprime les references a co dans les etapes suivantes
293 self.parent.delete_concept_after_etape(self,co)
295 self.sdprods.append(co)
298 for e in self.etapes:
302 def supprime_sdprod(self,sd):
304 Supprime le concept produit sd s'il est produit par l'etape
306 if sd in self.sdprods:
308 self.parent.del_sdprod(sd)
309 self.sdprods.remove(sd)
311 self.parent.delete_concept(sd)
314 if sd is not self.sd :return
315 if self.sd is not None :
317 self.parent.del_sdprod(sd)
320 self.parent.delete_concept(sd)
322 def supprime_sdprods(self):
324 Fonction: Lors de la destruction de la macro-etape, detruit tous les concepts produits
325 Un opérateur n a qu un concept produit
326 Une procedure n'en a aucun
327 Une macro en a en général plus d'un
329 #print "supprime_sdprods"
330 if self.reuse is not self.sd :
331 # l'étape n'est pas réentrante
332 # le concept retourné par l'étape est à supprimer car il était
335 self.parent.del_sdprod(self.sd)
336 self.parent.delete_concept(self.sd)
337 # On détruit les concepts à droite du signe =
338 for co in self.sdprods:
339 self.parent.del_sdprod(co)
340 self.parent.delete_concept(co)
341 # Si la macro a des etapes et des concepts inclus, on les detruit
342 for nom_sd,co in self.g_context.items():
343 if not isinstance(co,ASSD):continue
344 self.parent.del_sdprod(co)
345 self.parent.delete_concept(co)
346 # On met g_context à blanc
351 if hasattr(self,"jdc_aux") and self.jdc_aux:
352 # La macro a un jdc auxiliaire inclus. On demande sa fermeture
355 def reset_context(self):
356 if hasattr(self,"jdc_aux") and self.jdc_aux:
357 # La macro a un jdc auxiliaire inclus. On demande la reinitialisation du contexte
358 self.jdc_aux.reset_context()
360 def update_concept(self,sd):
361 I_ETAPE.ETAPE.update_concept(self,sd)
362 for etape in self.etapes:
363 etape.update_concept(sd)
365 def delete_concept(self,sd):
367 Fonction : Mettre a jour les mots cles de l etape et eventuellement
368 le concept produit si reuse suite à la disparition du concept sd
369 Seuls les mots cles simples MCSIMP font un traitement autre
370 que de transmettre aux fils
372 #print "delete_concept",sd
373 I_ETAPE.ETAPE.delete_concept(self,sd)
374 for etape in self.etapes:
375 etape.delete_concept(sd)
377 def replace_concept(self,old_sd,sd):
379 Fonction : Mettre a jour les mots cles de l etape et le concept produit si reuse
380 suite au remplacement du concept old_sd par sd
382 #print "replace_concept",old_sd,sd
383 I_ETAPE.ETAPE.replace_concept(self,old_sd,sd)
384 for etape in self.etapes:
385 etape.replace_concept(old_sd,sd)
387 def change_fichier_init(self,new_fic,text):
389 Tente de changer le fichier include. Le precedent include est conservé
392 #print "change_fichier_init",new_fic
393 if not hasattr(self,'fichier_ini'):
394 self.fichier_ini=None
395 self.fichier_text=None
396 self.fichier_err="Le fichier n'est pas defini"
397 self.contexte_fichier_init={}
398 self.recorded_units={}
400 self.fichier_unite="PasDefini"
401 import Extensions.jdc_include
402 self.JdC_aux=Extensions.jdc_include.JdC_include
404 self.old_fic = self.fichier_ini
405 self.old_text = self.fichier_text
406 self.old_err = self.fichier_err
407 self.old_context=self.contexte_fichier_init
408 self.old_units=self.recorded_units
409 self.old_etapes=self.etapes
410 self.old_jdc_aux=self.jdc_aux
412 self.fichier_ini = new_fic
413 self.fichier_text=text
416 self.make_contexte_include(new_fic,text)
418 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
419 self.fichier_err=string.join(l)
422 # L'evaluation de text dans un JDC auxiliaire s'est bien passé
423 # on peut poursuivre le traitement
425 self.state="undetermined"
426 self.fichier_err=None
427 # On enregistre la modification de fichier
429 # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
430 self.parent.reset_context()
432 # Si des concepts ont disparu lors du changement de fichier, on demande leur suppression
433 self.old_contexte_fichier_init=self.old_context
434 self.reevalue_sd_jdc()
438 self.old_jdc_aux.close()
440 def restore_fichier_init(self):
442 Restaure le fichier init enregistre dans old_xxx
444 self.fichier_ini=self.old_fic
445 self.fichier_text=self.old_text
446 self.fichier_err=self.old_err
447 self.contexte_fichier_init=self.old_context
448 self.recorded_units=self.old_units
449 self.etapes=self.old_etapes
450 self.jdc_aux=self.old_jdc_aux
452 def force_fichier_init(self):
454 Force le remplacement du fichier init meme si le remplacant est en erreur
456 # Reinitialisation complete du compte-rendu d'erreurs
457 self.jdc_aux.cr=self.jdc_aux.CR()
458 # On remplit le dictionnaire des concepts produits inclus
459 # en retirant les concepts présents dans le contexte initial
460 # On ajoute egalement le concept produit dans le sds_dict du parent
461 # sans verification car on est sur (verification integrée) que
462 # le nommage est possible
463 j_context=self.jdc_aux.get_contexte_avant(None)
464 self.g_context.clear()
465 context_ini=self.jdc_aux.context_ini
466 for k,v in j_context.items():
467 if not context_ini.has_key(k) or context_ini[k] != v:
469 self.parent.sds_dict[k]=v
470 # On recupere le contexte courant
471 self.current_context=self.jdc_aux.current_context
472 self.index_etape_courante=self.jdc_aux.index_etape_courante
473 self.contexte_fichier_init = j_context
474 self.fichier_err = None
476 # On enregistre la modification de fichier
478 self.state="undetermined"
480 # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
481 self.parent.reset_context()
483 # On remplace les anciens concepts par les nouveaux (y compris ajouts
484 # et suppression) et on propage les modifications aux etapes precedentes et suivantes
485 # reevalue_sd_jdc construit la liste des differences entre les contextes contexte_fichier_init
486 # et old_contexte_fichier_init et effectue les destructions et remplacements de concept
488 self.old_contexte_fichier_init=self.old_context
489 self.reevalue_sd_jdc()
492 self.old_jdc_aux.close()
494 self.jdc_aux.force_contexte(self.g_context)
496 def build_include(self,fichier,text):
497 import Extensions.jdc_include
498 self.JdC_aux=Extensions.jdc_include.JdC_include
499 # un include partage la table des unites avec son parent (jdc)
500 self.recorded_units=self.parent.recorded_units
501 self.build_jdcaux(fichier,text)
503 def build_poursuite(self,fichier,text):
504 import Extensions.jdc_include
505 self.JdC_aux=Extensions.jdc_include.JdC_poursuite
506 # une poursuite a sa propre table d'unites
507 self.recorded_units={}
508 self.build_jdcaux(fichier,text)
510 def build_jdcaux(self,fichier,text):
512 Cree un jdc auxiliaire initialise avec text.
513 Initialise le nom du fichier associé avec fichier
514 N'enregistre pas d'association unite <-> fichier
516 self.fichier_ini = fichier
517 self.fichier_text= text
518 self.fichier_unite=None
519 self.fichier_err = None
521 contexte = self.get_contexte_jdc(fichier,text)
522 if contexte is None :
523 # Impossible de construire le jdc auxiliaire (sortie par None)
524 # On simule une sortie par exception
525 raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
527 # La construction du jdc auxiliaire est allée au bout
528 self.contexte_fichier_init = contexte
532 # Impossible de construire le jdc auxiliaire (sortie par exception)
533 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
535 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
536 message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
541 self.fichier_err = string.join(l)
542 self.contexte_fichier_init={}
547 def make_contexte_include(self,fichier,text):
549 Cette méthode sert à créer un contexte en interprétant un texte source Python.
551 #print "make_contexte_include",fichier
552 # on récupère le contexte d'un nouveau jdc dans lequel on interprete text
553 contexte = self.get_contexte_jdc(fichier,text)
554 if contexte == None :
555 raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
557 # Pour les macros de type include : INCLUDE, INCLUDE_MATERIAU et POURSUITE
558 # l'attribut g_context est un dictionnaire qui contient les concepts produits par inclusion
559 # l'attribut contexte_fichier_init est un dictionnaire qui contient les concepts produits
560 # en sortie de macro. g_context est obtenu en retirant de contexte_fichier_init les concepts
561 # existants en debut de macro contenus dans context_ini (dans get_contexte_jdc)
562 # g_context est utilisé pour avoir les concepts produits par la macro
563 # contexte_fichier_init est utilisé pour avoir les concepts supprimés par la macro
564 self.contexte_fichier_init = contexte
566 def reevalue_fichier_init_OBSOLETE(self):
567 """Recalcule les concepts produits par le fichier enregistre"""
568 #print "reevalue_fichier_init"
569 old_context=self.contexte_fichier_init
571 self.make_contexte_include(self.fichier_ini ,self.fichier_text)
573 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
574 self.fichier_err = string.join(l)
578 self.old_contexte_fichier_init=old_context
579 self.contexte_fichier_init={}
580 self.reevalue_sd_jdc()
583 # L'evaluation s'est bien passee
584 self.fichier_err = None
585 self.old_contexte_fichier_init=old_context
586 self.reevalue_sd_jdc()
588 def update_fichier_init(self,unite):
589 """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur
590 les noms des fichiers
591 Ceci suppose que les relations entre unites et noms ont été memorisees préalablement
592 L'include a été initialisé précédemment. Le jdc auxiliaire existe.
594 #print "update_fichier_init",unite,self.fichier_unite
595 self.old_contexte_fichier_init=self.contexte_fichier_init
596 old_fichier_ini=self.fichier_ini
597 if not hasattr(self,"jdc_aux"):self.jdc_aux=None
598 old_jdc_aux=self.jdc_aux
600 #print "update_fichier_init",self,self.parent,self.parent.recorded_units
602 if self.fichier_unite is None:
603 # L'unité n'était pas définie précédemment. On ne change que l'unite
604 #print "update_fichier_init","pas de changement dans include"
605 self.fichier_unite=unite
607 elif unite == self.fichier_unite :
608 # L'unité n'a pas changé
609 #print "update_fichier_init","pas de changement dans include 3"
611 elif unite != self.fichier_unite :
612 # L'unité était définie précédemment. On remplace l'include
614 f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
616 # Le fichier associé n'a pas pu etre defini
617 # on change l'unite associée mais pas l'include
618 #print "update_fichier_init","pas de changement dans include 2"
619 self.fichier_unite=unite
623 self.fichier_text=text
624 self.fichier_unite=unite
625 #print "update_fichier_init",self.recorded_units
627 #print "update_fichier_init",self.fichier_ini,self.fichier_text,self.fichier_unite
629 if old_fichier_ini == self.fichier_ini:
630 # Le fichier inclus n'a pas changé. On ne recrée pas le contexte
631 # mais on enregistre le changement d'association unite <-> fichier
632 #print "update_fichier_init.fichier inchange",self.jdc_aux.context_ini
633 self.parent.record_unit(unite,self)
637 self.fichier_err=None
638 self.make_contexte_include(self.fichier_ini,self.fichier_text)
639 # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects
640 # avant d'appeler change_unit
642 # Erreurs lors de l'evaluation de text dans un JDC auxiliaire
643 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
644 # On conserve la memoire du nouveau fichier
645 # mais on n'utilise pas les concepts crees par ce fichier
646 # on met l'etape en erreur : fichier_err=string.join(l)
647 self.fichier_err=string.join(l)
651 self.contexte_fichier_init={}
655 self.parent.record_unit(unite,self)
656 # Le contexte du parent doit etre reinitialise car les concepts
657 # produits ont changé
658 self.parent.reset_context()
659 # Si des concepts ont disparu lors du changement de fichier, on
660 # demande leur suppression
661 self.reevalue_sd_jdc()
662 #print "update_fichier_init",self.jdc_aux.context_ini.keys()
664 def record_unite(self):
665 #print "record_unite",self.nom
666 if self.nom == "POURSUITE":
667 self.parent.record_unit(None,self)
669 if hasattr(self,'fichier_unite') :
670 self.parent.record_unit(self.fichier_unite,self)
672 def get_file_memo(self,unite=None,fic_origine=''):
673 """Retourne le nom du fichier et le source correspondant a l'unite unite
674 Initialise en plus recorded_units
676 #print "get_file_memo",unite,fic_origine,self,self.parent
677 #print self.parent.recorded_units
679 # On est dans le cas d'une poursuite. On ne reutilise aucune unite de parent
682 # On est dans le cas d'un include. On reutilise toutes les unites de parent
683 units=self.parent.recorded_units
685 if self.parent.recorded_units.has_key(unite):
686 f,text,units=self.parent.recorded_units[unite]
688 f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
692 self.recorded_units=units
693 if f is None and self.jdc.appli:
694 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
695 message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
698 def update_context(self,d):
700 Met à jour le contexte contenu dans le dictionnaire d
701 Une MACRO_ETAPE peut ajouter plusieurs concepts dans le contexte
702 Une fonction enregistree dans op_init peut egalement modifier le contexte
704 #print "update_context",self,self.nom,d.keys()
705 if hasattr(self,"jdc_aux") and self.jdc_aux:
706 #ATTENTION: update_context NE DOIT PAS appeler reset_context
707 # car il appelle directement ou indirectement update_context
708 # equivalent a reset_context. Evite les recursions
709 self.jdc_aux.context_ini=d.copy()
710 self.jdc_aux.current_context={}
711 self.jdc_aux.index_etape_courante=0
712 #ATTENTION: il ne faut pas utiliser self.jdc_aux.get_contexte_avant
713 #car cet appel conduit a des remontées multiples incohérentes dans le
715 #get_context_avant appelle update_context qui NE DOIT PAS appeler get_contexte_avant
716 #On n'a besoin que d'un update local connaissant
717 # le contexte amont : d qui sert a reinitialiser self.context_ini
718 for e in self.etapes:
722 if type(self.definition.op_init) == types.FunctionType:
723 apply(self.definition.op_init,(self,d))
724 if self.sd != None:d[self.sd.nom]=self.sd
725 for co in self.sdprods:
727 #print "update_context.fin",d.keys()
729 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
731 etape=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.copy(self)
732 if hasattr(etape,"etapes") :etape.etapes=[]
733 if hasattr(etape,"jdc_aux") :
735 del etape.fichier_ini
739 #print "supprime",self
740 if hasattr(self,"jdc_aux") and self.jdc_aux:
741 self.jdc_aux.supprime_aux()
743 Noyau.N_MACRO_ETAPE.MACRO_ETAPE.supprime(self)
744 # self.contexte_fichier_init={}
745 # self.old_contexte_fichier_init={}
747 # self.current_context={}
751 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
752 def get_file(self,unite=None,fic_origine=''):
753 """Retourne le nom du fichier et le source correspondant a l'unite unite
756 f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
761 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
762 def make_include(self,unite=None):
764 Inclut un fichier dont l'unite logique est unite
765 Cette methode est appelee par la fonction sd_prod de la macro INCLUDE
766 Si l'INCLUDE est invalide, la methode doit produire une exception
767 Sinon on retourne None. Les concepts produits par l'INCLUDE sont
768 pris en compte par le JDC parent lors du calcul du contexte (appel de ???)
770 #print "make_include",unite
771 # On supprime l'attribut unite qui bloque l'evaluation du source de l'INCLUDE
772 # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
773 # Si unite n'a pas de valeur, l'etape est forcement invalide. On peut retourner None
774 if not unite : return
776 if not hasattr(self,'fichier_ini') :
777 # Si le fichier n'est pas defini on le demande
778 f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
779 # On memorise le fichier retourne
781 self.fichier_text = text
782 self.contexte_fichier_init={}
783 self.fichier_unite=unite
784 self.fichier_err=None
786 import Extensions.jdc_include
788 traceback.print_exc()
790 self.JdC_aux=Extensions.jdc_include.JdC_include
792 #print "make_include",self.fichier_ini,self.fichier_text
793 if f is None and not text:
794 self.fichier_err="Le fichier INCLUDE n est pas defini"
795 self.parent.record_unit(unite,self)
796 raise Exception(self.fichier_err)
799 self.make_contexte_include(self.fichier_ini ,self.fichier_text)
800 self.parent.record_unit(unite,self)
801 #print "make_include.context_ini",self.jdc_aux.context_ini
803 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
805 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
806 message="Le contenu de ce fichier ne sera pas pris en compte\n"+string.join(l)
808 self.parent.record_unit(unite,self)
812 self.fichier_err = string.join(l)
813 self.contexte_fichier_init={}
817 # Si le fichier est deja defini on ne reevalue pas le fichier
818 # et on leve une exception si une erreur a été enregistrée
819 self.update_fichier_init(unite)
820 self.fichier_unite=unite
821 if self.fichier_err is not None: raise Exception(self.fichier_err)
824 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
825 def make_contexte(self,fichier,text):
827 Cette méthode sert à créer un contexte pour INCLUDE_MATERIAU
828 en interprétant un texte source Python
829 Elle est appelee par la fonction sd_prod d'INCLUDE_MATERIAU
831 #print "make_contexte",fichier
832 # On supprime l'attribut mat qui bloque l'evaluation du source de l'INCLUDE_MATERIAU
833 # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
834 if hasattr(self,'mat'):del self.mat
835 if not hasattr(self,'fichier_ini') or self.fichier_ini != fichier or self.fichier_mater != self.nom_mater:
836 # le fichier est nouveau ou change
837 self.fichier_ini =fichier
838 self.fichier_unite =fichier
839 self.fichier_mater=self.nom_mater
840 self.fichier_text=text
841 self.fichier_err=None
842 self.contexte_fichier_init={}
843 # On specifie la classe a utiliser pour le JDC auxiliaire
845 import Extensions.jdc_include
846 self.JdC_aux=Extensions.jdc_include.JdC_include
850 self.make_contexte_include(self.fichier_ini ,self.fichier_text)
851 if not self.g_context.has_key(self.nom_mater):
852 #Pour permettre de lire un jeu de commandes avec des INCLUDE_MATERIAU errones
853 self.g_context[self.nom_mater]=None
854 if self.parent: self.parent.g_context[self.nom_mater]=None
856 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
857 self.fichier_err = string.join(l)
859 #Pour permettre de lire un jeu de commandes avec des INCLUDE_MATERIAU errones
861 self.parent.g_context[self.nom_mater]=None
862 self.g_context[self.nom_mater]=None
866 self.contexte_fichier_init={}
869 # le fichier est le meme on ne le reevalue pas
870 # et on leve une exception si une erreur a été enregistrée
871 if self.fichier_err is not None: raise Exception(self.fichier_err)
873 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
874 def update_sdprod(self,cr='non'):
875 # Cette methode peut etre appelee dans EFICAS avec des mots cles de
876 # la commande modifies. Ceci peut conduire a la construction ou
877 # a la reconstruction d'etapes dans le cas d'INCLUDE ou d'INCLUDE_MATERIAU
878 # Il faut donc positionner le current_step avant l'appel
879 CONTEXT.unset_current_step()
880 CONTEXT.set_current_step(self)
881 valid=Validation.V_MACRO_ETAPE.MACRO_ETAPE.update_sdprod(self,cr=cr)
882 CONTEXT.unset_current_step()
885 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro
886 def Build_sd(self,nom):
888 Methode de Noyau surchargee pour poursuivre malgre tout
889 si une erreur se produit pendant la creation du concept produit
892 sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom)
893 except AsException,e:
894 # Une erreur s'est produite lors de la construction du concept
895 # Comme on est dans EFICAS, on essaie de poursuivre quand meme
896 # Si on poursuit, on a le choix entre deux possibilités :
897 # 1. on annule la sd associée à self
898 # 2. on la conserve mais il faut la retourner
899 # On choisit de l'annuler
900 # En plus il faut rendre coherents sdnom et sd.nom
903 self.state="unchanged"
908 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro
909 def make_poursuite(self):
910 """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE
912 #print "make_poursuite"
913 if not hasattr(self,'fichier_ini') :
914 # Si le fichier n'est pas defini on le demande
915 f,text=self.get_file_memo(fic_origine=self.parent.nom)
916 # On memorise le fichier retourne
918 self.fichier_unite = None
919 self.fichier_text = text
920 self.fichier_err=None
922 import Extensions.jdc_include
924 traceback.print_exc()
926 self.JdC_aux=Extensions.jdc_include.JdC_poursuite
927 self.contexte_fichier_init={}
928 #print "make_poursuite",self.fichier_ini,self.fichier_text
931 self.fichier_err="Le fichier POURSUITE n'est pas defini"
933 self.parent.record_unit(None,self)
934 raise Exception(self.fichier_err)
937 self.make_contexte_include(self.fichier_ini,self.fichier_text)
938 self.parent.record_unit(None,self)
940 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
942 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier poursuite",
943 message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
945 self.parent.record_unit(None,self)
949 self.fichier_err = string.join(l)
950 self.contexte_fichier_init={}
954 # Si le fichier est deja defini on ne reevalue pas le fichier
955 # et on leve une exception si une erreur a été enregistrée
956 self.update_fichier_init(None)
957 if self.fichier_err is not None: raise Exception(self.fichier_err)