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 format=self.jdc.appli.format_fichier.get()
114 if convert.plugins.has_key(format):
115 # Le convertisseur existe on l'utilise
116 p=convert.plugins[format]()
118 text=p.convert('exec',self.jdc.appli)
119 #Si le fichier ne peut pas etre converti, le cr n'est pas vide
120 #et le texte est retourné tel que
121 if not p.cr.estvide():
122 self.text_converted=0
123 self.text_error=str(p.cr)
125 self.text_converted=1
127 j=self.JdC_aux( procedure=text, nom=fichier,
128 appli=self.jdc.appli,
130 cata_ord_dico=self.jdc.cata_ordonne_dico,
131 context_ini = context_ini,
132 jdc_pere=self.jdc,etape_include=self,
133 prefix_include=prefix_include,
134 recorded_units=self.recorded_units,
135 old_recorded_units=old_recorded_units,**args)
138 # On récupère les étapes internes (pour validation)
142 traceback.print_exc()
143 # On retablit l'etape courante step
144 CONTEXT.unset_current_step()
145 CONTEXT.set_current_step(step)
148 if not j.cr.estvide():
149 # Erreurs dans l'INCLUDE. On garde la memoire du fichier
150 # mais on n'insere pas les concepts
151 # On retablit l'etape courante step
153 CONTEXT.unset_current_step()
154 CONTEXT.set_current_step(step)
155 raise Exception("Impossible de relire le fichier\n"+str(j.cr))
158 # L'INCLUDE n'est pas valide.
159 # on produit un rapport d'erreurs
162 # On retablit l'etape courante step
163 CONTEXT.unset_current_step()
164 CONTEXT.set_current_step(step)
165 raise Exception("Le fichier include contient des erreurs\n"+str(cr))
167 # Si aucune erreur rencontrée
168 # On recupere le contexte de l'include verifie
170 j_context=j.get_verif_contexte()
171 #print j_context.keys()
172 #print j.g_context.keys()
174 # On retablit l'etape courante step
175 CONTEXT.unset_current_step()
176 CONTEXT.set_current_step(step)
179 # Si on est arrivé ici, le texte du fichier inclus (INCLUDE, POURSUITE, ...)
180 # est valide et insérable dans le JDC
182 # On remplit le dictionnaire des concepts produits inclus
183 # en retirant les concepts présents dans le contexte initial
184 # On ajoute egalement le concept produit dans le sds_dict du parent
185 # sans verification car on est sur (verification integrée) que
186 # le nommage est possible
187 self.g_context.clear()
188 for k,v in j_context.items():
189 if not context_ini.has_key(k) or context_ini[k] != v:
191 self.parent.sds_dict[k]=v
193 #Ce traitement n'est réalisé que dans les cas suivants:
194 # - si convert n'a pas pu convertir le jeu de commandes
195 # - et ce n'est pas un INCLUDE_MATERIAU
196 #On collecte les variables Python qui ne sont pas dans le contexte initial
197 #et dans le contexte validé et on en fait un pseudo-parametre (Variable)
198 if self.text_converted == 0 and self.nom != "INCLUDE_MATERIAU":
199 for k,v in j.g_context.items():
200 if k in context_ini:continue
201 if k in j_context:continue
202 if isinstance(v,ASSD):continue
203 if isinstance(v,I_ENTITE.ENTITE):continue
204 if isinstance(v,I_OBJECT.OBJECT):continue
205 if callable(v):continue
206 self.g_context[k]=param2.Variable(k,v)
208 # On recupere le contexte courant
209 self.current_context=j.current_context
210 self.index_etape_courante=j.index_etape_courante
213 # On retablit l'etape courante step
214 CONTEXT.unset_current_step()
215 CONTEXT.set_current_step(step)
219 def reevalue_sd_jdc(self):
221 Avec la liste des SD qui ont été supprimées, propage la
222 disparition de ces SD dans toutes les étapes et descendants
224 #print "reevalue_sd_jdc"
225 l_sd_supp,l_sd_repl = self.diff_contextes()
227 self.parent.delete_concept_after_etape(self,sd)
228 for old_sd,sd in l_sd_repl:
229 self.parent.replace_concept_after_etape(self,old_sd,sd)
231 def diff_contextes(self):
233 Réalise la différence entre les 2 contextes
234 old_contexte_fichier_init et contexte_fichier_init
235 cad retourne la liste des sd qui ont disparu ou ne derivent pas
236 de la meme classe et des sd qui ont ete remplacees
238 if not hasattr(self,'old_contexte_fichier_init'):return [],[]
241 for old_key in self.old_contexte_fichier_init.keys():
242 if not self.contexte_fichier_init.has_key(old_key):
243 if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
244 l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
246 if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
247 # Un concept de meme nom existe
248 old_class=self.old_contexte_fichier_init[old_key].__class__
249 if not isinstance(self.contexte_fichier_init[old_key],old_class):
250 # S'il n'est pas d'une classe derivee, on le supprime
251 l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
253 l_sd_replaced.append((self.old_contexte_fichier_init[old_key],self.contexte_fichier_init[old_key]))
254 return l_sd_suppressed,l_sd_replaced
256 def control_sdprods(self,d):
258 Cette methode doit verifier que les concepts produits par la
259 commande ne sont pas incompatibles avec le contexte fourni (d).
260 Si c'est le cas, le concept produit doit etre supprime
261 Si la macro a elle meme des etapes, elle doit propager
262 le traitement (voir methode control_jdc_context_apres de I_JDC)
264 #print "I_MACRO_ETAPE.control_sdprods",d.keys(),self.nom,self.sd and self.sd.nom
266 if d.has_key(self.sd.nom):
267 # Le concept est deja defini
268 if self.reuse and self.reuse is d[self.sd.nom]:
269 # Le concept est reutilise : situation normale
272 # Redefinition du concept, on l'annule
273 #XXX on pourrait simplement annuler son nom pour conserver les objets
274 # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
277 self.sd=self.reuse=self.sdnom=None
278 self.parent.delete_concept_after_etape(self,sd)
281 # On verifie les concepts a droite du signe =
283 sdprods=self.sdprods[:]
286 if d.has_key(co.nom) and co is not d[co.nom] :
287 #nettoie les mots cles de l'étape qui ont comme valeur co
288 self.delete_concept(co)
289 #supprime les references a co dans les etapes suivantes
290 self.parent.delete_concept_after_etape(self,co)
292 self.sdprods.append(co)
295 for e in self.etapes:
299 def supprime_sdprod(self,sd):
301 Supprime le concept produit sd s'il est produit par l'etape
303 if sd in self.sdprods:
305 self.parent.del_sdprod(sd)
306 self.sdprods.remove(sd)
308 self.parent.delete_concept(sd)
311 if sd is not self.sd :return
312 if self.sd is not None :
314 self.parent.del_sdprod(sd)
317 self.parent.delete_concept(sd)
319 def supprime_sdprods(self):
321 Fonction: Lors de la destruction de la macro-etape, detruit tous les concepts produits
322 Un opérateur n a qu un concept produit
323 Une procedure n'en a aucun
324 Une macro en a en général plus d'un
326 #print "supprime_sdprods"
327 if self.reuse is not self.sd :
328 # l'étape n'est pas réentrante
329 # le concept retourné par l'étape est à supprimer car il était
332 self.parent.del_sdprod(self.sd)
333 self.parent.delete_concept(self.sd)
334 # On détruit les concepts à droite du signe =
335 for co in self.sdprods:
336 self.parent.del_sdprod(co)
337 self.parent.delete_concept(co)
338 # Si la macro a des etapes et des concepts inclus, on les detruit
339 for nom_sd,co in self.g_context.items():
340 if not isinstance(co,ASSD):continue
341 self.parent.del_sdprod(co)
342 self.parent.delete_concept(co)
343 # On met g_context à blanc
348 if hasattr(self,"jdc_aux") and self.jdc_aux:
349 # La macro a un jdc auxiliaire inclus. On demande sa fermeture
352 def reset_context(self):
353 if hasattr(self,"jdc_aux") and self.jdc_aux:
354 # La macro a un jdc auxiliaire inclus. On demande la reinitialisation du contexte
355 self.jdc_aux.reset_context()
357 def update_concept(self,sd):
358 I_ETAPE.ETAPE.update_concept(self,sd)
359 for etape in self.etapes:
360 etape.update_concept(sd)
362 def delete_concept(self,sd):
364 Fonction : Mettre a jour les mots cles de l etape et eventuellement
365 le concept produit si reuse suite à la disparition du concept sd
366 Seuls les mots cles simples MCSIMP font un traitement autre
367 que de transmettre aux fils
369 #print "delete_concept",sd
370 I_ETAPE.ETAPE.delete_concept(self,sd)
371 for etape in self.etapes:
372 etape.delete_concept(sd)
374 def replace_concept(self,old_sd,sd):
376 Fonction : Mettre a jour les mots cles de l etape et le concept produit si reuse
377 suite au remplacement du concept old_sd par sd
379 #print "replace_concept",old_sd,sd
380 I_ETAPE.ETAPE.replace_concept(self,old_sd,sd)
381 for etape in self.etapes:
382 etape.replace_concept(old_sd,sd)
384 def change_fichier_init(self,new_fic,text):
386 Tente de changer le fichier include. Le precedent include est conservé
389 #print "change_fichier_init",new_fic
390 if not hasattr(self,'fichier_ini'):
391 self.fichier_ini=None
392 self.fichier_text=None
393 self.fichier_err="Le fichier n'est pas defini"
394 self.contexte_fichier_init={}
395 self.recorded_units={}
397 self.fichier_unite="PasDefini"
398 import Extensions.jdc_include
399 self.JdC_aux=Extensions.jdc_include.JdC_include
401 self.old_fic = self.fichier_ini
402 self.old_text = self.fichier_text
403 self.old_err = self.fichier_err
404 self.old_context=self.contexte_fichier_init
405 self.old_units=self.recorded_units
406 self.old_etapes=self.etapes
407 self.old_jdc_aux=self.jdc_aux
409 self.fichier_ini = new_fic
410 self.fichier_text=text
413 self.make_contexte_include(new_fic,text)
415 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
416 self.fichier_err=string.join(l)
419 # L'evaluation de text dans un JDC auxiliaire s'est bien passé
420 # on peut poursuivre le traitement
422 self.state="undetermined"
423 self.fichier_err=None
424 # On enregistre la modification de fichier
426 # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
427 self.parent.reset_context()
429 # Si des concepts ont disparu lors du changement de fichier, on demande leur suppression
430 self.old_contexte_fichier_init=self.old_context
431 self.reevalue_sd_jdc()
435 self.old_jdc_aux.close()
437 def restore_fichier_init(self):
439 Restaure le fichier init enregistre dans old_xxx
441 self.fichier_ini=self.old_fic
442 self.fichier_text=self.old_text
443 self.fichier_err=self.old_err
444 self.contexte_fichier_init=self.old_context
445 self.recorded_units=self.old_units
446 self.etapes=self.old_etapes
447 self.jdc_aux=self.old_jdc_aux
449 def force_fichier_init(self):
451 Force le remplacement du fichier init meme si le remplacant est en erreur
453 # Reinitialisation complete du compte-rendu d'erreurs
454 self.jdc_aux.cr=self.jdc_aux.CR()
455 # On remplit le dictionnaire des concepts produits inclus
456 # en retirant les concepts présents dans le contexte initial
457 # On ajoute egalement le concept produit dans le sds_dict du parent
458 # sans verification car on est sur (verification integrée) que
459 # le nommage est possible
460 j_context=self.jdc_aux.get_contexte_avant(None)
461 self.g_context.clear()
462 context_ini=self.jdc_aux.context_ini
463 for k,v in j_context.items():
464 if not context_ini.has_key(k) or context_ini[k] != v:
466 self.parent.sds_dict[k]=v
467 # On recupere le contexte courant
468 self.current_context=self.jdc_aux.current_context
469 self.index_etape_courante=self.jdc_aux.index_etape_courante
470 self.contexte_fichier_init = j_context
471 self.fichier_err = None
473 # On enregistre la modification de fichier
475 self.state="undetermined"
477 # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
478 self.parent.reset_context()
480 # On remplace les anciens concepts par les nouveaux (y compris ajouts
481 # et suppression) et on propage les modifications aux etapes precedentes et suivantes
482 # reevalue_sd_jdc construit la liste des differences entre les contextes contexte_fichier_init
483 # et old_contexte_fichier_init et effectue les destructions et remplacements de concept
485 self.old_contexte_fichier_init=self.old_context
486 self.reevalue_sd_jdc()
489 self.old_jdc_aux.close()
491 self.jdc_aux.force_contexte(self.g_context)
493 def build_include(self,fichier,text):
494 import Extensions.jdc_include
495 self.JdC_aux=Extensions.jdc_include.JdC_include
496 # un include partage la table des unites avec son parent (jdc)
497 self.recorded_units=self.parent.recorded_units
498 self.build_jdcaux(fichier,text)
500 def build_poursuite(self,fichier,text):
501 import Extensions.jdc_include
502 self.JdC_aux=Extensions.jdc_include.JdC_poursuite
503 # une poursuite a sa propre table d'unites
504 self.recorded_units={}
505 self.build_jdcaux(fichier,text)
507 def build_jdcaux(self,fichier,text):
509 Cree un jdc auxiliaire initialise avec text.
510 Initialise le nom du fichier associé avec fichier
511 N'enregistre pas d'association unite <-> fichier
513 self.fichier_ini = fichier
514 self.fichier_text= text
515 self.fichier_unite=None
516 self.fichier_err = None
518 contexte = self.get_contexte_jdc(fichier,text)
519 if contexte is None :
520 # Impossible de construire le jdc auxiliaire (sortie par None)
521 # On simule une sortie par exception
522 raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
524 # La construction du jdc auxiliaire est allée au bout
525 self.contexte_fichier_init = contexte
529 # Impossible de construire le jdc auxiliaire (sortie par exception)
530 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
532 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
533 message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
538 self.fichier_err = string.join(l)
539 self.contexte_fichier_init={}
544 def make_contexte_include(self,fichier,text):
546 Cette méthode sert à créer un contexte en interprétant un texte source Python.
548 #print "make_contexte_include",fichier
549 # on récupère le contexte d'un nouveau jdc dans lequel on interprete text
550 contexte = self.get_contexte_jdc(fichier,text)
551 if contexte == None :
552 raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
554 # Pour les macros de type include : INCLUDE, INCLUDE_MATERIAU et POURSUITE
555 # l'attribut g_context est un dictionnaire qui contient les concepts produits par inclusion
556 # l'attribut contexte_fichier_init est un dictionnaire qui contient les concepts produits
557 # en sortie de macro. g_context est obtenu en retirant de contexte_fichier_init les concepts
558 # existants en debut de macro contenus dans context_ini (dans get_contexte_jdc)
559 # g_context est utilisé pour avoir les concepts produits par la macro
560 # contexte_fichier_init est utilisé pour avoir les concepts supprimés par la macro
561 self.contexte_fichier_init = contexte
563 def reevalue_fichier_init_OBSOLETE(self):
564 """Recalcule les concepts produits par le fichier enregistre"""
565 #print "reevalue_fichier_init"
566 old_context=self.contexte_fichier_init
568 self.make_contexte_include(self.fichier_ini ,self.fichier_text)
570 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
571 self.fichier_err = string.join(l)
575 self.old_contexte_fichier_init=old_context
576 self.contexte_fichier_init={}
577 self.reevalue_sd_jdc()
580 # L'evaluation s'est bien passee
581 self.fichier_err = None
582 self.old_contexte_fichier_init=old_context
583 self.reevalue_sd_jdc()
585 def update_fichier_init(self,unite):
586 """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur
587 les noms des fichiers
588 Ceci suppose que les relations entre unites et noms ont été memorisees préalablement
589 L'include a été initialisé précédemment. Le jdc auxiliaire existe.
591 #print "update_fichier_init",unite,self.fichier_unite
592 self.old_contexte_fichier_init=self.contexte_fichier_init
593 old_fichier_ini=self.fichier_ini
594 if not hasattr(self,"jdc_aux"):self.jdc_aux=None
595 old_jdc_aux=self.jdc_aux
597 #print "update_fichier_init",self,self.parent,self.parent.recorded_units
599 if self.fichier_unite is None:
600 # L'unité n'était pas définie précédemment. On ne change que l'unite
601 #print "update_fichier_init","pas de changement dans include"
602 self.fichier_unite=unite
604 elif unite == self.fichier_unite :
605 # L'unité n'a pas changé
606 #print "update_fichier_init","pas de changement dans include 3"
608 elif unite != self.fichier_unite :
609 # L'unité était définie précédemment. On remplace l'include
611 f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
613 # Le fichier associé n'a pas pu etre defini
614 # on change l'unite associée mais pas l'include
615 #print "update_fichier_init","pas de changement dans include 2"
616 self.fichier_unite=unite
620 self.fichier_text=text
621 self.fichier_unite=unite
622 #print "update_fichier_init",self.recorded_units
624 #print "update_fichier_init",self.fichier_ini,self.fichier_text,self.fichier_unite
626 if old_fichier_ini == self.fichier_ini:
627 # Le fichier inclus n'a pas changé. On ne recrée pas le contexte
628 # mais on enregistre le changement d'association unite <-> fichier
629 #print "update_fichier_init.fichier inchange",self.jdc_aux.context_ini
630 self.parent.record_unit(unite,self)
634 self.fichier_err=None
635 self.make_contexte_include(self.fichier_ini,self.fichier_text)
636 # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects
637 # avant d'appeler change_unit
639 # Erreurs lors de l'evaluation de text dans un JDC auxiliaire
640 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
641 # On conserve la memoire du nouveau fichier
642 # mais on n'utilise pas les concepts crees par ce fichier
643 # on met l'etape en erreur : fichier_err=string.join(l)
644 self.fichier_err=string.join(l)
648 self.contexte_fichier_init={}
652 self.parent.record_unit(unite,self)
653 # Le contexte du parent doit etre reinitialise car les concepts
654 # produits ont changé
655 self.parent.reset_context()
656 # Si des concepts ont disparu lors du changement de fichier, on
657 # demande leur suppression
658 self.reevalue_sd_jdc()
659 #print "update_fichier_init",self.jdc_aux.context_ini.keys()
661 def record_unite(self):
662 #print "record_unite",self.nom
663 if self.nom == "POURSUITE":
664 self.parent.record_unit(None,self)
666 if hasattr(self,'fichier_unite') :
667 self.parent.record_unit(self.fichier_unite,self)
669 def get_file_memo(self,unite=None,fic_origine=''):
670 """Retourne le nom du fichier et le source correspondant a l'unite unite
671 Initialise en plus recorded_units
673 #print "get_file_memo",unite,fic_origine,self,self.parent
674 #print self.parent.recorded_units
676 # On est dans le cas d'une poursuite. On ne reutilise aucune unite de parent
679 # On est dans le cas d'un include. On reutilise toutes les unites de parent
680 units=self.parent.recorded_units
682 if self.parent.recorded_units.has_key(unite):
683 f,text,units=self.parent.recorded_units[unite]
685 f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
689 self.recorded_units=units
690 if f is None and self.jdc.appli:
691 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
692 message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
695 def update_context(self,d):
697 Met à jour le contexte contenu dans le dictionnaire d
698 Une MACRO_ETAPE peut ajouter plusieurs concepts dans le contexte
699 Une fonction enregistree dans op_init peut egalement modifier le contexte
701 #print "update_context",self,self.nom,d.keys()
702 if hasattr(self,"jdc_aux") and self.jdc_aux:
703 #ATTENTION: update_context NE DOIT PAS appeler reset_context
704 # car il appelle directement ou indirectement update_context
705 # equivalent a reset_context. Evite les recursions
706 self.jdc_aux.context_ini=d.copy()
707 self.jdc_aux.current_context={}
708 self.jdc_aux.index_etape_courante=0
709 #ATTENTION: il ne faut pas utiliser self.jdc_aux.get_contexte_avant
710 #car cet appel conduit a des remontées multiples incohérentes dans le
712 #get_context_avant appelle update_context qui NE DOIT PAS appeler get_contexte_avant
713 #On n'a besoin que d'un update local connaissant
714 # le contexte amont : d qui sert a reinitialiser self.context_ini
715 for e in self.etapes:
719 if type(self.definition.op_init) == types.FunctionType:
720 apply(self.definition.op_init,(self,d))
721 if self.sd != None:d[self.sd.nom]=self.sd
722 for co in self.sdprods:
724 #print "update_context.fin",d.keys()
726 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
728 etape=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.copy(self)
729 if hasattr(etape,"etapes") :etape.etapes=[]
730 if hasattr(etape,"jdc_aux") :
732 del etape.fichier_ini
736 #print "supprime",self
737 if hasattr(self,"jdc_aux") and self.jdc_aux:
738 self.jdc_aux.supprime_aux()
740 Noyau.N_MACRO_ETAPE.MACRO_ETAPE.supprime(self)
741 # self.contexte_fichier_init={}
742 # self.old_contexte_fichier_init={}
744 # self.current_context={}
748 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
749 def get_file(self,unite=None,fic_origine=''):
750 """Retourne le nom du fichier et le source correspondant a l'unite unite
753 f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
758 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
759 def make_include(self,unite=None):
761 Inclut un fichier dont l'unite logique est unite
762 Cette methode est appelee par la fonction sd_prod de la macro INCLUDE
763 Si l'INCLUDE est invalide, la methode doit produire une exception
764 Sinon on retourne None. Les concepts produits par l'INCLUDE sont
765 pris en compte par le JDC parent lors du calcul du contexte (appel de ???)
767 #print "make_include",unite
768 # On supprime l'attribut unite qui bloque l'evaluation du source de l'INCLUDE
769 # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
771 # Si unite n'a pas de valeur, l'etape est forcement invalide. On peut retourner None
772 if not unite : return
774 if not hasattr(self,'fichier_ini') :
775 # Si le fichier n'est pas defini on le demande
776 f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
777 # On memorise le fichier retourne
779 self.fichier_text = text
780 self.contexte_fichier_init={}
781 self.fichier_unite=unite
782 self.fichier_err=None
784 import Extensions.jdc_include
786 traceback.print_exc()
788 self.JdC_aux=Extensions.jdc_include.JdC_include
790 #print "make_include",self.fichier_ini,self.fichier_text
791 if f is None and not text:
792 self.fichier_err="Le fichier INCLUDE n est pas defini"
793 self.parent.record_unit(unite,self)
794 raise Exception(self.fichier_err)
797 self.make_contexte_include(self.fichier_ini ,self.fichier_text)
798 self.parent.record_unit(unite,self)
799 #print "make_include.context_ini",self.jdc_aux.context_ini
801 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
803 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
804 message="Le contenu de ce fichier ne sera pas pris en compte\n"+string.join(l)
806 self.parent.record_unit(unite,self)
810 self.fichier_err = string.join(l)
811 self.contexte_fichier_init={}
815 # Si le fichier est deja defini on ne reevalue pas le fichier
816 # et on leve une exception si une erreur a été enregistrée
817 self.update_fichier_init(unite)
818 self.fichier_unite=unite
819 if self.fichier_err is not None: raise Exception(self.fichier_err)
822 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
823 def make_contexte(self,fichier,text):
825 Cette méthode sert à créer un contexte pour INCLUDE_MATERIAU
826 en interprétant un texte source Python
827 Elle est appelee par la fonction sd_prod d'INCLUDE_MATERIAU
829 #print "make_contexte",fichier
830 # On supprime l'attribut mat qui bloque l'evaluation du source de l'INCLUDE_MATERIAU
831 # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
832 if hasattr(self,'mat'):del self.mat
833 if not hasattr(self,'fichier_ini') or self.fichier_ini != fichier or self.fichier_mater != self.nom_mater:
834 # le fichier est nouveau ou change
835 self.fichier_ini =fichier
836 self.fichier_unite =fichier
837 self.fichier_mater=self.nom_mater
838 self.fichier_text=text
839 self.fichier_err=None
840 self.contexte_fichier_init={}
841 # On specifie la classe a utiliser pour le JDC auxiliaire
843 import Extensions.jdc_include
844 self.JdC_aux=Extensions.jdc_include.JdC_include
848 self.make_contexte_include(self.fichier_ini ,self.fichier_text)
849 if not self.g_context.has_key(self.nom_mater):
850 #Pour permettre de lire un jeu de commandes avec des INCLUDE_MATERIAU errones
851 self.g_context[self.nom_mater]=None
852 if self.parent: self.parent.g_context[self.nom_mater]=None
854 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
855 self.fichier_err = string.join(l)
857 #Pour permettre de lire un jeu de commandes avec des INCLUDE_MATERIAU errones
859 self.parent.g_context[self.nom_mater]=None
860 self.g_context[self.nom_mater]=None
864 self.contexte_fichier_init={}
867 # le fichier est le meme on ne le reevalue pas
868 # et on leve une exception si une erreur a été enregistrée
869 if self.fichier_err is not None: raise Exception(self.fichier_err)
871 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
872 def update_sdprod(self,cr='non'):
873 # Cette methode peut etre appelee dans EFICAS avec des mots cles de
874 # la commande modifies. Ceci peut conduire a la construction ou
875 # a la reconstruction d'etapes dans le cas d'INCLUDE ou d'INCLUDE_MATERIAU
876 # Il faut donc positionner le current_step avant l'appel
877 CONTEXT.unset_current_step()
878 CONTEXT.set_current_step(self)
879 valid=Validation.V_MACRO_ETAPE.MACRO_ETAPE.update_sdprod(self,cr=cr)
880 CONTEXT.unset_current_step()
883 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro
884 def Build_sd(self,nom):
886 Methode de Noyau surchargee pour poursuivre malgre tout
887 si une erreur se produit pendant la creation du concept produit
890 sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom)
891 except AsException,e:
892 # Une erreur s'est produite lors de la construction du concept
893 # Comme on est dans EFICAS, on essaie de poursuivre quand meme
894 # Si on poursuit, on a le choix entre deux possibilités :
895 # 1. on annule la sd associée à self
896 # 2. on la conserve mais il faut la retourner
897 # On choisit de l'annuler
898 # En plus il faut rendre coherents sdnom et sd.nom
901 self.state="unchanged"
906 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro
907 def make_poursuite(self):
908 """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE
910 #print "make_poursuite"
911 if not hasattr(self,'fichier_ini') :
912 # Si le fichier n'est pas defini on le demande
913 f,text=self.get_file_memo(fic_origine=self.parent.nom)
914 # On memorise le fichier retourne
916 self.fichier_unite = None
917 self.fichier_text = text
918 self.fichier_err=None
920 import Extensions.jdc_include
922 traceback.print_exc()
924 self.JdC_aux=Extensions.jdc_include.JdC_poursuite
925 self.contexte_fichier_init={}
926 #print "make_poursuite",self.fichier_ini,self.fichier_text
929 self.fichier_err="Le fichier POURSUITE n'est pas defini"
931 self.parent.record_unit(None,self)
932 raise Exception(self.fichier_err)
935 self.make_contexte_include(self.fichier_ini,self.fichier_text)
936 self.parent.record_unit(None,self)
938 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
940 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier poursuite",
941 message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
943 self.parent.record_unit(None,self)
947 self.fichier_err = string.join(l)
948 self.contexte_fichier_init={}
952 # Si le fichier est deja defini on ne reevalue pas le fichier
953 # et on leve une exception si une erreur a été enregistrée
954 self.update_fichier_init(None)
955 if self.fichier_err is not None: raise Exception(self.fichier_err)