5 import string,linecache
9 from Noyau.N_ASSD import ASSD
10 from Noyau.N_ETAPE import ETAPE
11 from Noyau.N_Exception import AsException
12 from Extensions import commentaire,parametre,parametre_eval
14 class JDC(I_OBJECT.OBJECT):
19 self.etapes_niveaux=[]
23 self._etape_context=None
25 def get_cmd(self,nomcmd):
27 Retourne l'objet de type COMMANDE de nom nomcmd
29 for cata in self.cata:
30 if hasattr(cata,nomcmd):
31 return getattr(cata,nomcmd)
33 def get_sd_avant_du_bon_type(self,etape,types_permis):
35 Retourne la liste des concepts avant etape d'un type acceptable
37 d=self.get_contexte_avant(etape)
40 if type(v) != types.InstanceType : continue
41 # On considère que seul assd indique un type quelconque pas CO
42 elif self.assd in types_permis :
44 elif self.est_permis(v,types_permis):
49 def est_permis(self,v,types_permis):
50 for type_ok in types_permis:
51 if type_ok in ('R','I','C','TXM') and v in self.params :
53 elif type_ok == 'R' and v.__class__.__name__ == 'reel' :
55 elif type_ok == 'I' and v.__class__.__name__ == 'entier' :
57 elif type_ok == 'C' and v.__class__.__name__ == 'complexe' :
59 elif type_ok == 'TXM' and v.__class__.__name__ == 'chaine' :
61 elif type(type_ok) != types.ClassType :
63 elif v.__class__ == type_ok or issubclass(v.__class__,type_ok):
67 def addentite(self,name,pos):
70 Si name est le nom d une commande ou un commentaire ajoute
72 Sinon remonte une erreur
76 if name == "COMMENTAIRE" :
77 # ajout d'un commentaire
78 self.set_current_step()
80 for child in self.etapes :
81 if isinstance(child,commentaire.COMMENTAIRE):
83 objet = commentaire.COMMENTAIRE('',parent=self)
84 objet.nom = "_comm_"+`ind`
85 if pos == None : pos = 0
86 self.etapes.insert(pos,objet)
90 elif name == "PARAMETRE":
91 # ajout d'un parametre
92 self.set_current_step()
93 nom_param = '_param_'+str(len(self.params)+1)
94 objet = parametre.PARAMETRE(nom=nom_param)
95 if pos == None : pos = 0
96 self.etapes.insert(pos,objet)
101 elif name == "PARAMETRE_EVAL":
102 # ajout d'un parametre EVAL
103 self.set_current_step()
104 nom_param = '_param_'+str(len(self.params)+1)
105 objet = parametre_eval.PARAMETRE_EVAL(nom=nom_param)
106 if pos == None : pos = 0
107 self.etapes.insert(pos,objet)
112 elif type(name)==types.InstanceType:
113 # on est dans le cas où on veut ajouter une commande déjà
114 # existante (par copie donc)
115 # on est donc nécessairement en mode editeur ...
117 # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
119 self.set_current_step()
120 if isinstance(objet,ETAPE):
121 if objet.nom_niveau_definition == 'JDC':
122 # l'objet dépend directement du JDC
125 # l'étape dépend d'un niveau et non directement du JDC :
126 # il faut l'enregistrer dans le niveau de parent
127 objet.parent.dict_niveaux[objet.nom_niveau_definition].register(objet)
128 objet.niveau = objet.parent.dict_niveaux[objet.nom_niveau_definition]
129 self.etapes.insert(pos,objet)
130 # il faut vérifier que les concepts utilisés par objet existent bien
131 # à ce niveau d'arborescence
132 objet.verif_existence_sd()
138 # On veut ajouter une nouvelle commande
140 self.set_current_step()
141 cmd=self.get_cmd(name)
142 # L'appel a make_objet n'a pas pour effet d'enregistrer l'étape
143 # auprès du step courant car editmode vaut 1
144 # Par contre elle a le bon parent grace a set_current_step
146 if pos == None : pos = 0
147 self.etapes.insert(pos,e)
148 self.reset_current_step()
154 traceback.print_exc()
155 self.reset_current_step()
157 raise AsException("Impossible d ajouter la commande "+name)
159 def set_current_step(self):
160 CONTEXT.unset_current_step()
161 CONTEXT.set_current_step(self)
163 def reset_current_step(self):
164 CONTEXT.unset_current_step()
166 def liste_mc_presents(self):
169 def get_sd_avant_etape(self,nom_sd,etape):
170 return self.get_contexte_avant(etape).get(nom_sd,None)
172 def get_sd_apres_etape(self,nom_sd,etape,avec='non'):
174 Cette méthode retourne la SD de nom nom_sd qui est éventuellement
176 Si avec vaut 'non' exclut etape de la recherche
178 ietap=self.etapes.index(etape)
179 if avec == 'non':ietap=ietap+1
180 for e in self.etapes[ietap:]:
181 sd=e.get_sdprods(nom_sd)
183 if hasattr(e,'reuse'):
188 def get_sd_autour_etape(self,nom_sd,etape,avec='non'):
190 Fonction: retourne la SD de nom nom_sd qui est éventuellement
191 définie avant ou apres etape
192 Permet de vérifier si un concept de meme nom existe dans le périmètre
194 Si avec vaut 'non' exclut etape de la recherche
196 sd=self.get_sd_avant_etape(nom_sd,etape)
198 return self.get_sd_apres_etape(nom_sd,etape,avec)
200 def active_etapes(self):
202 Cette méthode a pour fonction de désactiver les étapes qui doivent
203 l'être cad, dans le cas d'ASTER, les étapes qui ne sont pas
204 comprises entre le premier DEBUT/POURSUITE et le premier FIN
205 et rendre actives les autres
207 if self.definition.code == 'ASTER' :
208 # Seulement pour ASTER :
209 # Avant DEBUT actif vaut 0
210 # Apres DEBUT et avant le 1er FIN actif vaut 1
211 # Apres le 1er FIN actif vaut -1
215 for etape in self.etapes:
216 if actif == 0 and etape.nom in ['DEBUT','POURSUITE']:actif=1
221 if etape.nom == 'FIN':actif=-1
223 def suppentite(self,etape) :
225 Cette methode a pour fonction de supprimer une étape dans
229 self.etapes.remove(etape)
230 if etape.niveau is not self:
231 # Dans ce cas l'étape est enregistrée dans un niveau
232 # Il faut la désenregistrer
233 etape.niveau.unregister(etape)
234 etape.supprime_sdprods()
237 def del_sdprod(self,sd):
239 Supprime la SD sd de la liste des sd et des dictionnaires de contexte
241 if sd in self.sds : self.sds.remove(sd)
242 if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
244 def delete_concept(self,sd):
249 Mettre a jour les etapes du JDC suite à la disparition du
251 Seuls les mots cles simples MCSIMP font un traitement autre
252 que de transmettre aux fils
254 for etape in self.etapes :
255 etape.delete_concept(sd)
259 if not self.cr.estvide():return
263 def register(self,etape):
265 Cette méthode ajoute etape dans la liste
266 des etapes self.etapes et retourne l identificateur d'étape
267 fourni par l appel a g_register
268 A quoi sert editmode ?
269 - Si editmode vaut 1, on est en mode edition de JDC. On cherche
270 à enregistrer une étape que l'on a créée avec eficas (en passant
271 par addentite) auquel cas on ne veut récupérer que son numéro
272 d'enregistrement et c'est addentité qui l'enregistre dans
273 self.etapes à la bonne place...
274 - Si editmode vaut 0, on est en mode relecture d'un fichier de
275 commandes et on doit enregistrer l'étape à la fin de self.etapes
276 (dans ce cas l'ordre des étapes est bien l'ordre chronologique
279 if not self.editmode:
280 self.etapes.append(etape)
283 return self.g_register(etape)
285 def register_parametre(self,param):
287 Cette méthode sert à ajouter un paramètre dans la liste des paramètres
289 self.params.append(param)
291 def register_fonction(self,fonction):
293 Cette méthode sert à ajouter une fonction dans la liste des fonctions
295 self.fonctions.append(fonction)
297 def delete_param(self,param):
299 Supprime le paramètre param de la liste des paramètres
302 if param in self.params : self.params.remove(param)
303 if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
305 def get_parametres_fonctions_avant_etape(self,etape):
307 Retourne deux éléments :
308 - une liste contenant les noms des paramètres (constantes ou EVAL)
310 - une liste contenant les formules définies avant etape
314 # on récupère le contexte avant etape
315 # on ne peut mettre dans les deux listes que des éléments de ce contexte
316 d=self.get_contexte_avant(etape)
317 # construction de l_constantes
318 for param in self.params:
320 if not nom : continue
321 if d.has_key(nom): l_constantes.append(nom)
322 # construction de l_fonctions
323 for form in self.fonctions:
325 if not nom : continue
326 if d.has_key(nom): l_fonctions.append(form.get_formule())
328 # on ajoute les concepts produits par DEFI_VALEUR
329 # XXX On pourrait peut etre faire plutot le test sur le type
330 # de concept : entier, reel, complexe, etc.
331 for k,v in d.items():
332 if hasattr(v,'etape') and v.etape.nom in ('DEFI_VALEUR',):
333 l_constantes.append(k)
335 # on retourne les deux listes
336 return l_constantes,l_fonctions
338 def get_nb_etapes_avant(self,niveau):
340 Retourne le nombre d etapes avant le debut de niveau
343 for niv in self.etapes_niveaux:
344 if niv == niveau:break
345 nb=nb+len(niv.etapes)
348 def send_message(self,message):
350 self.appli.send_message(message)
352 #XXX ne semble pas servir pour JDC
353 # def reevalue_sd_jdc(self):
355 #Avec la liste des SD qui ont été supprimées, propage la disparition de ces
356 #SD dans toutes les étapes et descendants
358 #l_sd = self.diff_contextes()
359 #if len(l_sd) == 0 : return
361 #self.jdc.delete_concept(sd)
363 def init_modif(self):
365 Méthode appelée au moment où une modification va être faite afin de
366 déclencher d'éventuels traitements pré-modification
368 self.state = 'modified'
373 def get_liste_mc_inconnus(self):
375 Retourne une liste contenant les mots-clés inconnus à la relecture du JDC
377 # cette liste a le format suivant : [etape,(bloc,mcfact,...),nom_mc,valeur_mc]
379 for etape in self.etapes :
381 if not etape.isvalid() :
382 l = etape.get_liste_mc_inconnus()
383 if l : l_mc.extend(l)
386 def get_file(self,unite=None,fic_origine=''):
388 Retourne le nom du fichier correspondant à un numero d'unité
389 logique (entier) ainsi que le source contenu dans le fichier
392 # Si le JDC est relié à une application maitre, on délègue la recherche
393 file,text = self.appli.get_file(unite,fic_origine)
397 if os.path.exists("fort."+str(unite)):
398 file= "fort."+str(unite)
400 raise AsException("Impossible de trouver le fichier correspondant \
401 a l unite %s" % unite)
402 if not os.path.exists(file):
403 raise AsException("%s n'est pas un fichier existant" % unite)
407 text=string.replace(text,'\r\n','\n')
408 linecache.cache[file]=0,0,string.split(text,'\n'),file
412 def get_genealogie(self):
414 Retourne la liste des noms des ascendants de l'objet self
415 jusqu'à la première ETAPE parent.
419 def NommerSdprod(self,sd,sdnom):
421 Nomme la SD apres avoir verifie que le nommage est possible : nom
423 Si le nom est deja utilise, leve une exception
424 Met le concept créé dans le concept global g_context
426 # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
427 # Le dictionnaire g_context ne représente pas le contexte
428 # effectif avant une étape.
429 # Il faut utiliser get_contexte_avant avec une indication de l'étape
430 # traitée. Pour le moment, il n'y a pas de moyen de le faire : ajouter
431 # un attribut dans le JDC ???
432 if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
433 if self._etape_context:
434 o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
436 o=self.g_context.get(sdnom,None)
437 if isinstance(o,ASSD):
438 raise AsException("Nom de concept deja defini : %s" % sdnom)
440 # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
441 # Ajoute a la creation (appel de reg_sd).
442 self.g_context[sdnom]=sd
445 def set_etape_context(self,etape):
447 Positionne l'etape qui sera utilisee dans NommerSdProd pour
448 decider si le concept passé pourra etre nommé
450 self._etape_context=etape
452 def reset_context(self):
454 Cette methode reinitialise le contexte glissant pour pouvoir
455 tenir compte des modifications de l'utilisateur : création
456 de commandes, nommage de concepts, etc.
458 self.current_context={}
459 self.index_etape_courante=0
461 def del_param(self,param):
463 Supprime le paramètre param de la liste des paramètres
466 if param in self.params : self.params.remove(param)
467 if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
469 def del_fonction(self,fonction):
471 Supprime la fonction fonction de la liste des fonctions
474 if fonction in self.fonctions : self.fonctions.remove(fonction)
475 if self.g_context.has_key(fonction.nom) : del self.g_context[fonction.nom]