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
29 from Noyau.N_ASSD import ASSD
31 # import rajoutés suite à l'ajout de Build_sd --> à résorber
32 import Noyau, Validation.V_MACRO_ETAPE
33 from Noyau import N_Exception
34 from Noyau.N_Exception import AsException
35 import Accas # attention aux imports circulaires
36 # fin import à résorber
38 class MACRO_ETAPE(I_ETAPE.ETAPE):
42 self.recorded_units={}
44 def get_sdprods(self,nom_sd):
46 Fonction : retourne le concept produit par l etape de nom nom_sd
47 s il existe sinon None
49 if self.sd and self.sd.nom == nom_sd :return self.sd
50 for co in self.sdprods:
51 if co.nom == nom_sd:return co
52 if type(self.definition.op_init) == types.FunctionType:
54 apply(self.definition.op_init,(self,d))
55 return d.get(nom_sd,None)
58 def get_contexte_jdc(self,fichier,text):
60 Interprète text comme un texte de jdc et retourne le
62 cad le dictionnaire des sd disponibles à la dernière étape
63 Si text n'est pas un texte de jdc valide, retourne None
65 --> utilisée par ops.POURSUITE et INCLUDE
67 #print "get_contexte_jdc"
69 # on essaie de créer un objet JDC auxiliaire avec un contexte initial
70 # Attention get_contexte_avant retourne un dictionnaire qui contient
71 # le contexte courant. Ce dictionnaire est reactualise regulierement.
72 # Si on veut garder l'etat du contexte fige, il faut en faire une copie.
73 context_ini = self.parent.get_contexte_avant(self).copy()
75 # Indispensable avant de creer un nouveau JDC
76 CONTEXT.unset_current_step()
79 if hasattr(self,'prefix'):
80 prefix_include=self.prefix
81 # ATTENTION : le dictionnaire recorded_units sert à memoriser les unites des
82 # fichiers inclus. Il est preferable de garder le meme dictionnaire pendant
83 # tout le traitement et de ne pas le reinitialiser brutalement (utiliser
84 # clear plutot) si on ne veut pas perdre la memoire des unites.
85 # En principe si la memorisation est faite au bon moment il n'est pas necessaire
86 # de prendre cette precaution mais ce n'est pas vrai partout.
87 old_recorded_units=self.recorded_units.copy()
88 #print "get_contexte_jdc",id(self.recorded_units)
89 #self.recorded_units.clear()
91 j=self.JdC_aux( procedure=text, nom=fichier,
94 cata_ord_dico=self.jdc.cata_ordonne_dico,
95 context_ini = context_ini,
96 jdc_pere=self.jdc,etape_include=self,
97 prefix_include=prefix_include,
98 recorded_units=self.recorded_units,
99 old_recorded_units=old_recorded_units,**args)
102 # On récupère les étapes internes (pour validation)
105 #print "get_contexte_jdc",id(self.etapes)
107 traceback.print_exc()
108 # On force le contexte (etape courante) à self
109 CONTEXT.unset_current_step()
110 CONTEXT.set_current_step(self)
113 if not j.cr.estvide():
114 # Erreurs dans l'INCLUDE. On garde la memoire du fichier
115 # mais on n'insere pas les concepts
116 # On force le contexte (etape courante) à self
117 CONTEXT.unset_current_step()
118 CONTEXT.set_current_step(self)
119 raise Exception("Impossible de relire le fichier\n"+str(j.cr))
122 # L'INCLUDE n'est pas valide.
123 # on produit un rapport d'erreurs
124 # On force le contexte (etape courante) à self
126 CONTEXT.unset_current_step()
127 CONTEXT.set_current_step(self)
128 raise Exception("Le fichier include contient des erreurs\n"+str(cr))
130 # Si aucune erreur rencontrée
131 # On recupere le contexte de l'include verifie
132 #print "context_ini",j.context_ini
133 #print "g_context",j.g_context
135 j_context=j.get_verif_contexte()
137 CONTEXT.unset_current_step()
138 CONTEXT.set_current_step(self)
141 #print "context_ini",j.context_ini
143 # On remplit le dictionnaire des concepts produits inclus
144 # en retirant les concepts présents dans le contexte initial
145 # On ajoute egalement le concept produit dans le sds_dict du parent
146 # sans verification car on est sur (verification integrée) que
147 # le nommage est possible
148 self.g_context.clear()
149 for k,v in j_context.items():
150 if not context_ini.has_key(k) or context_ini[k] != v:
152 self.parent.sds_dict[k]=v
155 # On recupere le contexte courant
156 self.current_context=j.current_context
157 self.index_etape_courante=j.index_etape_courante
160 # XXX j.supprime() ???
161 # On rétablit le contexte (etape courante) à self
162 CONTEXT.unset_current_step()
163 CONTEXT.set_current_step(self)
164 #print "context_ini",self.jdc_aux.context_ini
168 def reevalue_sd_jdc(self):
170 Avec la liste des SD qui ont été supprimées, propage la
171 disparition de ces SD dans toutes les étapes et descendants
173 #print "reevalue_sd_jdc"
174 l_sd_supp,l_sd_repl = self.diff_contextes()
176 self.parent.delete_concept_after_etape(self,sd)
177 for old_sd,sd in l_sd_repl:
178 self.parent.replace_concept_after_etape(self,old_sd,sd)
180 def diff_contextes(self):
182 Réalise la différence entre les 2 contextes
183 old_contexte_fichier_init et contexte_fichier_init
184 cad retourne la liste des sd qui ont disparu ou ne derivent pas
185 de la meme classe et des sd qui ont ete remplacees
187 if not hasattr(self,'old_contexte_fichier_init'):return [],[]
190 for old_key in self.old_contexte_fichier_init.keys():
191 if not self.contexte_fichier_init.has_key(old_key):
192 if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
193 l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
195 if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
196 # Un concept de meme nom existe
197 old_class=self.old_contexte_fichier_init[old_key].__class__
198 if not isinstance(self.contexte_fichier_init[old_key],old_class):
199 # S'il n'est pas d'une classe derivee, on le supprime
200 l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
202 l_sd_replaced.append((self.old_contexte_fichier_init[old_key],self.contexte_fichier_init[old_key]))
203 return l_sd_suppressed,l_sd_replaced
205 def control_sdprods(self,d):
207 Cette methode doit updater le contexte fournit par
208 l'appelant en argument (d) en fonction de sa definition
209 tout en verifiant que ses concepts produits ne sont pas
210 deja definis dans le contexte
212 if hasattr(self,"fichier_unite"):
213 self.update_fichier_init(self.fichier_unite)
216 if type(self.definition.op_init) == types.FunctionType:
217 apply(self.definition.op_init,(self,d))
219 if d.has_key(self.sd.nom):
220 # Le concept est deja defini
221 if self.reuse and self.reuse is d[self.sd.nom]:
222 # Le concept est reutilise : situation normale
225 # Redefinition du concept, on l'annule
226 #XXX on pourrait simplement annuler son nom pour conserver les objets
227 # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
228 self.sd=self.reuse=self.sdnom=None
231 # Le concept n'est pas defini, on peut updater d
232 d[self.sd.nom]=self.sd
233 # On verifie les concepts a droite du signe =
234 for co in self.sdprods:
235 if d.has_key(co.nom) and co is not d[co.nom] :
236 self.delete_concept(co)
240 def supprime_sdprod(self,sd):
242 Supprime le concept produit sd s'il est produit par l'etape
244 if sd in self.sdprods:
246 self.parent.del_sdprod(sd)
247 self.sdprods.remove(sd)
249 self.parent.delete_concept(sd)
252 if sd is not self.sd :return
253 if self.sd is not None :
255 self.parent.del_sdprod(sd)
258 self.parent.delete_concept(sd)
260 def supprime_sdprods(self):
262 Fonction: Lors de la destruction de la macro-etape, detruit tous les concepts produits
263 Un opérateur n a qu un concept produit
264 Une procedure n'en a aucun
265 Une macro en a en général plus d'un
267 #print "supprime_sdprods"
268 if self.reuse is not self.sd :
269 # l'étape n'est pas réentrante
270 # le concept retourné par l'étape est à supprimer car il était
273 self.parent.del_sdprod(self.sd)
274 self.parent.delete_concept(self.sd)
275 # On détruit les concepts à droite du signe =
276 for co in self.sdprods:
277 self.parent.del_sdprod(co)
278 self.parent.delete_concept(co)
279 # Si la macro a des etapes et des concepts inclus, on les detruit
280 for nom_sd,co in self.g_context.items():
281 if not isinstance(co,ASSD):continue
282 self.parent.del_sdprod(co)
283 self.parent.delete_concept(co)
284 # On met g_context à blanc
287 def delete_concept(self,sd):
289 Fonction : Mettre a jour les mots cles de l etape et eventuellement
290 le concept produit si reuse suite à la disparition du concept sd
291 Seuls les mots cles simples MCSIMP font un traitement autre
292 que de transmettre aux fils
294 #print "delete_concept",sd
295 I_ETAPE.ETAPE.delete_concept(self,sd)
296 for etape in self.etapes:
297 etape.delete_concept(sd)
299 def replace_concept(self,old_sd,sd):
301 Fonction : Mettre a jour les mots cles de l etape et le concept produit si reuse
302 suite au remplacement du concept old_sd par sd
304 #print "replace_concept",old_sd,sd
305 I_ETAPE.ETAPE.replace_concept(self,old_sd,sd)
306 for etape in self.etapes:
307 etape.replace_concept(old_sd,sd)
309 def change_fichier_init(self,new_fic,text):
311 Tente de changer le fichier include. Le precedent include est conservé
314 if not hasattr(self,'fichier_ini'):
315 self.fichier_ini=None
316 self.fichier_text=None
317 self.fichier_err="Le fichier n'est pas defini"
318 self.contexte_fichier_init={}
319 self.recorded_units={}
321 self.fichier_unite="PasDefini"
322 import Extensions.jdc_include
323 self.JdC_aux=Extensions.jdc_include.JdC_include
325 self.old_fic = self.fichier_ini
326 self.old_text = self.fichier_text
327 self.old_err = self.fichier_err
328 self.old_context=self.contexte_fichier_init
329 self.old_units=self.recorded_units
330 self.old_etapes=self.etapes
331 self.old_jdc_aux=self.jdc_aux
333 self.fichier_ini = new_fic
334 self.fichier_text=text
337 self.make_contexte_include(new_fic,text)
339 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
340 self.fichier_err=string.join(l)
343 # L'evaluation de text dans un JDC auxiliaire s'est bien passé
344 # on peut poursuivre le traitement
346 self.state="undetermined"
347 self.fichier_err=None
348 # On enregistre la modification de fichier
350 # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
351 self.parent.reset_context()
353 # Si des concepts ont disparu lors du changement de fichier, on demande leur suppression
354 self.old_contexte_fichier_init=self.old_context
355 self.reevalue_sd_jdc()
359 def restore_fichier_init(self):
361 Restaure le fichier init enregistre dans old_xxx
363 self.fichier_ini=self.old_fic
364 self.fichier_text=self.old_text
365 self.fichier_err=self.old_err
366 self.contexte_fichier_init=self.old_context
367 self.recorded_units=self.old_units
368 self.etapes=self.old_etapes
369 self.jdc_aux=self.old_jdc_aux
371 def force_fichier_init(self):
373 Force le fichier init en erreur
375 j_context=self.jdc_aux.get_contexte_avant(None)
376 # On remplit le dictionnaire des concepts produits inclus
377 # en retirant les concepts présents dans le contexte initial
378 # On ajoute egalement le concept produit dans le sds_dict du parent
379 # sans verification car on est sur (verification integrée) que
380 # le nommage est possible
381 self.g_context.clear()
382 context_ini=self.jdc_aux.context_ini
383 for k,v in j_context.items():
384 if not context_ini.has_key(k) or context_ini[k] != v:
386 self.parent.sds_dict[k]=v
387 # On recupere le contexte courant
388 self.current_context=self.jdc_aux.current_context
389 self.index_etape_courante=self.jdc_aux.index_etape_courante
390 self.contexte_fichier_init = j_context
392 # On conserve la memoire du nouveau fichier
393 # mais on n'utilise pas les concepts crees par ce fichier
394 # on met l'etape en erreur : fichier_err=string.join(l)
396 self.state="undetermined"
397 # On enregistre la modification de fichier
401 # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
402 self.parent.reset_context()
404 self.old_contexte_fichier_init=self.old_context
405 #self.contexte_fichier_init={}
406 self.reevalue_sd_jdc()
409 self.jdc_aux.force_contexte(self.g_context)
412 def make_contexte_include(self,fichier,text):
414 Cette méthode sert à créer un contexte en interprétant un texte source
417 #print "make_contexte_include"
418 # on récupère le contexte d'un nouveau jdc dans lequel on interprete text
419 contexte = self.get_contexte_jdc(fichier,text)
420 if contexte == None :
421 raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
423 # Pour les macros de type include : INCLUDE, INCLUDE_MATERIAU et POURSUITE
424 # l'attribut g_context est un dictionnaire qui contient les concepts produits par inclusion
425 # l'attribut contexte_fichier_init est un dictionnaire qui contient les concepts produits
426 # en sortie de macro. g_context est obtenu en retirant de contexte_fichier_init les concepts
427 # existants en debut de macro contenus dans context_ini (dans get_contexte_jdc)
428 # g_context est utilisé pour avoir les concepts produits par la macro
429 # contexte_fichier_init est utilisé pour avoir les concepts supprimés par la macro
430 self.contexte_fichier_init = contexte
432 def reevalue_fichier_init_OBSOLETE(self):
433 """Recalcule les concepts produits par le fichier enregistre"""
434 #print "reevalue_fichier_init"
435 old_context=self.contexte_fichier_init
437 self.make_contexte_include(self.fichier_ini ,self.fichier_text)
439 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
440 self.fichier_err = string.join(l)
444 self.old_contexte_fichier_init=old_context
445 self.contexte_fichier_init={}
446 self.reevalue_sd_jdc()
449 # L'evaluation s'est bien passee
450 self.fichier_err = None
451 self.old_contexte_fichier_init=old_context
452 self.reevalue_sd_jdc()
453 #print "reevalue_fichier_init",self.jdc_aux.context_ini
455 def update_fichier_init(self,unite):
456 """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur
457 les noms des fichiers
458 Ceci suppose que les relations entre unites et noms ont été memorisees préalablement
460 #print "update_fichier_init",unite
461 self.fichier_err=None
462 self.old_contexte_fichier_init=self.contexte_fichier_init
463 old_fichier_ini=self.fichier_ini
465 #print "update_fichier_init",self,self.parent,self.parent.recorded_units
467 #if unite != self.fichier_unite or not self.parent.recorded_units.has_key(unite):
468 if not self.parent.recorded_units.has_key(unite):
470 f,text=self.get_file(unite=unite,fic_origine=self.parent.nom)
474 self.fichier_text=text
475 self.recorded_units=units
476 if self.fichier_ini is None and self.jdc.appli:
477 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
478 message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
481 f,text,units=self.parent.recorded_units[unite]
483 self.fichier_text=text
484 self.recorded_units=units
486 if self.fichier_ini is None:
487 # Le fichier n'est pas défini
488 self.fichier_err="Le fichier associé n'est pas défini"
489 self.parent.change_unit(unite,self,self.fichier_unite)
491 self.contexte_fichier_init={}
492 self.parent.reset_context()
493 self.reevalue_sd_jdc()
496 if old_fichier_ini == self.fichier_ini:
497 # Le fichier inclus n'a pas changé. On ne recrée pas le contexte
498 #print "update_fichier_init.fichier inchange",self.jdc_aux.context_ini
502 self.make_contexte_include(self.fichier_ini,self.fichier_text)
503 # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects
504 # avant d'appeler change_unit
505 self.parent.change_unit(unite,self,self.fichier_unite)
507 # Erreurs lors de l'evaluation de text dans un JDC auxiliaire
508 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
509 # On conserve la memoire du nouveau fichier
510 # mais on n'utilise pas les concepts crees par ce fichier
511 # on met l'etape en erreur : fichier_err=string.join(l)
512 self.fichier_err=string.join(l)
513 self.parent.change_unit(unite,self,self.fichier_unite)
515 self.contexte_fichier_init={}
517 # Le contexte du parent doit etre reinitialise car les concepts
518 # produits ont changé
519 self.parent.reset_context()
520 # Si des concepts ont disparu lors du changement de fichier, on
521 # demande leur suppression
522 self.reevalue_sd_jdc()
523 #print "update_fichier_init",self.jdc_aux.context_ini
525 def record_unite(self):
526 if self.nom == "POURSUITE":
527 self.parent.record_unit(None,self)
529 if hasattr(self,'fichier_unite') :
530 self.parent.record_unit(self.fichier_unite,self)
532 def get_file_memo(self,unite=None,fic_origine=''):
533 """Retourne le nom du fichier et le source correspondant a l'unite unite
534 Initialise en plus recorded_units
536 #print "get_file_memo",unite,fic_origine,self,self.parent
537 #print self.parent.old_recorded_units
538 #print self.parent.recorded_units
542 units=self.parent.recorded_units
543 if self.parent.old_recorded_units.has_key(unite):
544 f,text,units=self.parent.old_recorded_units[unite]
545 #print id(self.recorded_units)
546 self.recorded_units=units
547 #print id(self.recorded_units)
550 f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
553 self.recorded_units=units
554 if f is None and self.jdc.appli:
555 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
556 message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
559 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
560 def get_file(self,unite=None,fic_origine=''):
561 """Retourne le nom du fichier et le source correspondant a l'unite unite
562 Initialise en plus recorded_units
564 #print "get_file",unite
567 f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
570 self.recorded_units=units
573 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
574 def make_include(self,unite=None):
576 Inclut un fichier dont l'unite logique est unite
577 Cette methode est appelee par la fonction sd_prod de la macro INCLUDE
578 Si l'INCLUDE est invalide, la methode doit produire une exception
579 Sinon on retourne None. Les concepts produits par l'INCLUDE sont
580 pris en compte par le JDC parent lors du calcul du contexte (appel de ???)
582 #print "make_include",unite
583 # On supprime l'attribut unite qui bloque l'evaluation du source de l'INCLUDE
584 # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
586 # Si unite n'a pas de valeur, l'etape est forcement invalide. On peut retourner None
587 if not unite : return
589 if not hasattr(self,'fichier_ini') :
590 # Si le fichier n'est pas defini on le demande
591 f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
592 # On memorise le fichier retourne
594 self.fichier_text = text
595 self.contexte_fichier_init={}
596 self.fichier_unite=unite
597 self.fichier_err=None
599 import Extensions.jdc_include
601 traceback.print_exc()
603 self.JdC_aux=Extensions.jdc_include.JdC_include
606 self.fichier_err="Le fichier INCLUDE n est pas defini"
607 self.parent.record_unit(unite,self)
608 raise Exception(self.fichier_err)
611 self.make_contexte_include(self.fichier_ini ,self.fichier_text)
612 self.parent.record_unit(unite,self)
613 #print "make_include.context_ini",self.jdc_aux.context_ini
615 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
617 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
618 message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
620 self.parent.record_unit(unite,self)
622 self.fichier_err = string.join(l)
623 self.contexte_fichier_init={}
627 # Si le fichier est deja defini on ne reevalue pas le fichier
628 # et on leve une exception si une erreur a été enregistrée
629 self.update_fichier_init(unite)
630 self.fichier_unite=unite
631 if self.fichier_err is not None: raise Exception(self.fichier_err)
634 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
635 def make_contexte(self,fichier,text):
637 Cette méthode sert à créer un contexte pour INCLUDE_MATERIAU
638 en interprétant un texte source Python
639 Elle est appelee par la fonction sd_prd d'INCLUDE_MATERIAU
641 # On supprime l'attribut mat qui bloque l'evaluation du source de l'INCLUDE_MATERIAU
642 # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
643 if hasattr(self,'mat'):del self.mat
644 self.fichier_ini =fichier
645 self.fichier_unite =fichier
646 self.fichier_text=text
647 self.fichier_err=None
648 self.contexte_fichier_init={}
649 # On specifie la classe a utiliser pour le JDC auxiliaire
651 import Extensions.jdc_include
653 traceback.print_exc()
655 self.JdC_aux=Extensions.jdc_include.JdC_include
657 self.make_contexte_include(self.fichier_ini ,self.fichier_text)
658 self.parent.record_unit(self.fichier_unite,self)
660 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
661 self.fichier_err = string.join(l)
662 self.parent.record_unit(self.fichier_unite,self)
664 self.contexte_fichier_init={}
667 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
668 def update_sdprod(self,cr='non'):
669 # Cette methode peut etre appelee dans EFICAS avec des mots cles de
670 # la commande modifies. Ceci peut conduire a la construction ou
671 # a la reconstruction d'etapes dans le cas d'INCLUDE ou d'INCLUDE_MATERIAU
672 # Il faut donc positionner le current_step avant l'appel
673 CONTEXT.unset_current_step()
674 CONTEXT.set_current_step(self)
675 valid=Validation.V_MACRO_ETAPE.MACRO_ETAPE.update_sdprod(self,cr=cr)
676 CONTEXT.unset_current_step()
679 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro
680 def Build_sd(self,nom):
682 Methode de Noyau surchargee pour poursuivre malgre tout
683 si une erreur se produit pendant la creation du concept produit
686 sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom)
687 except AsException,e:
688 # Une erreur s'est produite lors de la construction du concept
689 # Comme on est dans EFICAS, on essaie de poursuivre quand meme
690 # Si on poursuit, on a le choix entre deux possibilités :
691 # 1. on annule la sd associée à self
692 # 2. on la conserve mais il faut la retourner
693 # On choisit de l'annuler
694 # En plus il faut rendre coherents sdnom et sd.nom
697 self.state="unchanged"
702 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro
703 def make_poursuite(self):
704 """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE
706 #print "make_poursuite"
707 if not hasattr(self,'fichier_ini') :
708 # Si le fichier n'est pas defini on le demande
709 f,text=self.get_file_memo(fic_origine=self.parent.nom)
710 # On memorise le fichier retourne
712 self.fichier_unite = None
713 self.fichier_text = text
714 self.fichier_err=None
716 import Extensions.jdc_include
718 traceback.print_exc()
720 self.JdC_aux=Extensions.jdc_include.JdC_poursuite
721 self.contexte_fichier_init={}
724 self.fichier_err="Le fichier POURSUITE n'est pas defini"
725 self.parent.record_unit(None,self)
726 raise Exception(self.fichier_err)
729 self.make_contexte_include(self.fichier_ini,self.fichier_text)
730 self.parent.record_unit(None,self)
732 l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
734 self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier poursuite",
735 message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
737 self.parent.record_unit(None,self)
739 self.fichier_err = string.join(l)
740 self.contexte_fichier_init={}
744 # Si le fichier est deja defini on ne reevalue pas le fichier
745 # et on leve une exception si une erreur a été enregistrée
746 self.update_fichier_init(None)
747 if self.fichier_err is not None: raise Exception(self.fichier_err)
749 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro
750 def type_sdprod(self,co,t):
752 Cette methode a pour fonction de typer le concept co avec le type t
753 dans les conditions suivantes
754 1- co est un concept produit de self
755 2- co est un concept libre : on le type et on l attribue à self
756 Elle enregistre egalement les concepts produits (on fait l hypothese
757 que la liste sdprods a été correctement initialisee, vide probablement)
759 #print "type_sdprod",co,t
760 if not hasattr(co,'etape'):
761 # Le concept vaut None probablement. On ignore l'appel
764 # On cherche a discriminer les differents cas de typage d'un concept
765 # produit par une macro qui est specifie dans un mot cle simple.
766 # On peut passer plusieurs fois par type_sdprod ce qui explique
767 # le nombre important de cas.
769 # Cas 1 : Le concept est libre. Il vient d'etre cree par CO(nom)
770 # Cas 2 : Le concept est produit par la macro. On est deja passe par type_sdprod.
771 # Cas semblable a Cas 1.
772 # Cas 3 : Le concept est produit par la macro englobante (parent). On transfere
773 # la propriete du concept de la macro parent a la macro courante (self)
774 # en verifiant que le type est valide
775 # Cas 4 : La concept est la propriete d'une etape fille. Ceci veut dire qu'on est
776 # deja passe par type_sdprod et que la propriete a ete transfere a une
777 # etape fille. Cas semblable a Cas 3.
778 # Cas 5 : Le concept est produit par une etape externe a la macro.
781 # Cas 1 : le concept est libre
782 # On l'attache a la macro et on change son type dans le type demande
783 # Recherche du mot cle simple associe au concept
784 mcs=self.get_mcs_with_co(co)
786 raise AsException("""Erreur interne.
787 Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co)
790 # Attention : la seule modif est ici : Accas.CO au lieu de CO
792 if not Accas.CO in mcs.definition.type:
793 raise AsException("""Erreur interne.
794 Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type))
797 self.sdprods.append(co)
799 elif co.etape== self:
800 # Cas 2 : le concept est produit par la macro (self)
801 # On est deja passe par type_sdprod (Cas 1 ou 3).
802 # Il suffit de le mettre dans la liste des concepts produits (self.sdprods)
803 # Le type du concept doit etre coherent avec le type demande (seulement derive)
804 if not isinstance(co,t):
805 raise AsException("""Erreur interne.
806 Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__))
807 self.sdprods.append(co)
809 elif co.etape== self.parent:
810 # Cas 3 : le concept est produit par la macro parente (self.parent)
811 # on transfere la propriete du concept a la macro fille
812 # et on change le type du concept comme demande
813 # Au prealable, on verifie que le concept existant (co) est une instance
814 # possible du type demande (t)
815 # Cette règle est normalement cohérente avec les règles de vérification des mots-clés
816 if not isinstance(co,t):
817 raise AsException("""
818 Impossible de changer le type du concept produit (%s) en (%s).
819 Le type actuel (%s) devrait etre une classe derivee du nouveau type (%s)""" % (co,t,co.__class__,t))
820 mcs=self.get_mcs_with_co(co)
822 raise AsException("""Erreur interne.
823 Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co)
825 if not Accas.CO in mcs.definition.type:
826 raise AsException("""Erreur interne.
827 Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type))
829 # On ne change pas le type car il respecte la condition isinstance(co,t)
831 self.sdprods.append(co)
833 elif self.issubstep(co.etape):
834 # Cas 4 : Le concept est propriété d'une sous etape de la macro (self).
835 # On est deja passe par type_sdprod (Cas 3 ou 1).
836 # Il suffit de le mettre dans la liste des concepts produits (self.sdprods)
837 # Le type du concept et t doivent etre derives.
838 # Il n'y a aucune raison pour que la condition ne soit pas verifiee.
839 if not isinstance(co,t):
840 raise AsException("""Erreur interne.
841 Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__))
842 self.sdprods.append(co)
845 # Cas 5 : le concept est produit par une autre étape