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)
135 # On veut ajouter une nouvelle commande
137 self.set_current_step()
138 cmd=self.get_cmd(name)
139 # L'appel a make_objet n'a pas pour effet d'enregistrer l'étape
140 # auprès du step courant car editmode vaut 1
141 # Par contre elle a le bon parent grace a set_current_step
143 if pos == None : pos = 0
144 self.etapes.insert(pos,e)
145 self.reset_current_step()
151 traceback.print_exc()
152 self.reset_current_step()
154 raise AsException("Impossible d ajouter la commande "+name)
156 def set_current_step(self):
157 CONTEXT.unset_current_step()
158 CONTEXT.set_current_step(self)
160 def reset_current_step(self):
161 CONTEXT.unset_current_step()
163 def liste_mc_presents(self):
166 def get_sd_avant_etape(self,nom_sd,etape):
167 return self.get_contexte_avant(etape).get(nom_sd,None)
169 def get_sd_apres_etape(self,nom_sd,etape,avec='non'):
171 Cette méthode retourne la SD de nom nom_sd qui est éventuellement
173 Si avec vaut 'non' exclut etape de la recherche
175 ietap=self.etapes.index(etape)
176 if avec == 'non':ietap=ietap+1
177 for e in self.etapes[ietap:]:
178 sd=e.get_sdprods(nom_sd)
180 if hasattr(e,'reuse'):
185 def get_sd_autour_etape(self,nom_sd,etape,avec='non'):
187 Fonction: retourne la SD de nom nom_sd qui est éventuellement
188 définie avant ou apres etape
189 Permet de vérifier si un concept de meme nom existe dans le périmètre
191 Si avec vaut 'non' exclut etape de la recherche
193 sd=self.get_sd_avant_etape(nom_sd,etape)
195 return self.get_sd_apres_etape(nom_sd,etape,avec)
197 def active_etapes(self):
199 Cette méthode a pour fonction de désactiver les étapes qui doivent
200 l'être cad, dans le cas d'ASTER, les étapes qui ne sont pas
201 comprises entre le premier DEBUT/POURSUITE et le premier FIN
202 et rendre actives les autres
204 if self.definition.code == 'ASTER' :
205 # Seulement pour ASTER :
206 # Avant DEBUT actif vaut 0
207 # Apres DEBUT et avant le 1er FIN actif vaut 1
208 # Apres le 1er FIN actif vaut -1
212 for etape in self.etapes:
213 if actif == 0 and etape.nom in ['DEBUT','POURSUITE']:actif=1
218 if etape.nom == 'FIN':actif=-1
220 def suppentite(self,etape) :
222 Cette methode a pour fonction de supprimer une étape dans
226 self.etapes.remove(etape)
227 if etape.niveau is not self:
228 # Dans ce cas l'étape est enregistrée dans un niveau
229 # Il faut la désenregistrer
230 etape.niveau.unregister(etape)
231 etape.supprime_sdprods()
234 def del_sdprod(self,sd):
236 Supprime la SD sd de la liste des sd et des dictionnaires de contexte
238 if sd in self.sds : self.sds.remove(sd)
239 if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
241 def delete_concept(self,sd):
246 Mettre a jour les etapes du JDC suite à la disparition du
248 Seuls les mots cles simples MCSIMP font un traitement autre
249 que de transmettre aux fils
251 for etape in self.etapes :
252 etape.delete_concept(sd)
256 if not self.cr.estvide():return
260 def register(self,etape):
262 Cette méthode ajoute etape dans la liste
263 des etapes self.etapes et retourne l identificateur d'étape
264 fourni par l appel a g_register
265 A quoi sert editmode ?
266 - Si editmode vaut 1, on est en mode edition de JDC. On cherche
267 à enregistrer une étape que l'on a créée avec eficas (en passant
268 par addentite) auquel cas on ne veut récupérer que son numéro
269 d'enregistrement et c'est addentité qui l'enregistre dans
270 self.etapes à la bonne place...
271 - Si editmode vaut 0, on est en mode relecture d'un fichier de
272 commandes et on doit enregistrer l'étape à la fin de self.etapes
273 (dans ce cas l'ordre des étapes est bien l'ordre chronologique
276 if not self.editmode:
277 self.etapes.append(etape)
280 return self.g_register(etape)
282 def register_parametre(self,param):
284 Cette méthode sert à ajouter un paramètre dans la liste des paramètres
286 self.params.append(param)
288 def register_fonction(self,fonction):
290 Cette méthode sert à ajouter une fonction dans la liste des fonctions
292 self.fonctions.append(fonction)
294 def delete_param(self,param):
296 Supprime le paramètre param de la liste des paramètres
299 if param in self.params : self.params.remove(param)
300 if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
302 def get_parametres_fonctions_avant_etape(self,etape):
304 Retourne deux éléments :
305 - une liste contenant les noms des paramètres (constantes ou EVAL)
307 - une liste contenant les formules définies avant etape
311 # on récupère le contexte avant etape
312 # on ne peut mettre dans les deux listes que des éléments de ce contexte
313 d=self.get_contexte_avant(etape)
314 # construction de l_constantes
315 for param in self.params:
317 if not nom : continue
318 if d.has_key(nom): l_constantes.append(nom)
319 # construction de l_fonctions
320 for form in self.fonctions:
322 if not nom : continue
323 if d.has_key(nom): l_fonctions.append(form.get_formule())
325 # on ajoute les concepts produits par DEFI_VALEUR
326 # XXX On pourrait peut etre faire plutot le test sur le type
327 # de concept : entier, reel, complexe, etc.
328 for k,v in d.items():
329 if hasattr(v,'etape') and v.etape.nom in ('DEFI_VALEUR',):
330 l_constantes.append(k)
332 # on retourne les deux listes
333 return l_constantes,l_fonctions
335 def get_nb_etapes_avant(self,niveau):
337 Retourne le nombre d etapes avant le debut de niveau
340 for niv in self.etapes_niveaux:
341 if niv == niveau:break
342 nb=nb+len(niv.etapes)
345 def send_message(self,message):
347 self.appli.send_message(message)
349 #XXX ne semble pas servir pour JDC
350 # def reevalue_sd_jdc(self):
352 #Avec la liste des SD qui ont été supprimées, propage la disparition de ces
353 #SD dans toutes les étapes et descendants
355 #l_sd = self.diff_contextes()
356 #if len(l_sd) == 0 : return
358 #self.jdc.delete_concept(sd)
360 def init_modif(self):
362 Méthode appelée au moment où une modification va être faite afin de
363 déclencher d'éventuels traitements pré-modification
365 self.state = 'modified'
370 def get_liste_mc_inconnus(self):
372 Retourne une liste contenant les mots-clés inconnus à la relecture du JDC
374 # cette liste a le format suivant : [etape,(bloc,mcfact,...),nom_mc,valeur_mc]
376 for etape in self.etapes :
378 if not etape.isvalid() :
379 l = etape.get_liste_mc_inconnus()
380 if l : l_mc.extend(l)
383 def get_file(self,unite=None,fic_origine=''):
385 Retourne le nom du fichier correspondant à un numero d'unité
386 logique (entier) ainsi que le source contenu dans le fichier
389 # Si le JDC est relié à une application maitre, on délègue la recherche
390 file,text = self.appli.get_file(unite,fic_origine)
394 if os.path.exists("fort."+str(unite)):
395 file= "fort."+str(unite)
397 raise AsException("Impossible de trouver le fichier correspondant \
398 a l unite %s" % unite)
399 if not os.path.exists(file):
400 raise AsException("%s n'est pas un fichier existant" % unite)
404 text=string.replace(text,'\r\n','\n')
405 linecache.cache[file]=0,0,string.split(text,'\n'),file
409 def get_genealogie(self):
411 Retourne la liste des noms des ascendants de l'objet self
412 jusqu'à la première ETAPE parent.
416 def NommerSdprod(self,sd,sdnom):
418 Nomme la SD apres avoir verifie que le nommage est possible : nom
420 Si le nom est deja utilise, leve une exception
421 Met le concept créé dans le concept global g_context
423 # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
424 # Le dictionnaire g_context ne représente pas le contexte
425 # effectif avant une étape.
426 # Il faut utiliser get_contexte_avant avec une indication de l'étape
427 # traitée. Pour le moment, il n'y a pas de moyen de le faire : ajouter
428 # un attribut dans le JDC ???
429 if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
430 if self._etape_context:
431 o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
433 o=self.g_context.get(sdnom,None)
434 if isinstance(o,ASSD):
435 raise AsException("Nom de concept deja defini : %s" % sdnom)
437 # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
438 # Ajoute a la creation (appel de reg_sd).
439 self.g_context[sdnom]=sd
442 def set_etape_context(self,etape):
444 Positionne l'etape qui sera utilisee dans NommerSdProd pour
445 decider si le concept passé pourra etre nommé
447 self._etape_context=etape
449 def reset_context(self):
451 Cette methode reinitialise le contexte glissant pour pouvoir
452 tenir compte des modifications de l'utilisateur : création
453 de commandes, nommage de concepts, etc.
455 self.current_context={}
456 self.index_etape_courante=0
458 def del_param(self,param):
460 Supprime le paramètre param de la liste des paramètres
463 if param in self.params : self.params.remove(param)
464 if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
466 def del_fonction(self,fonction):
468 Supprime la fonction fonction de la liste des fonctions
471 if fonction in self.fonctions : self.fonctions.remove(fonction)
472 if self.g_context.has_key(fonction.nom) : del self.g_context[fonction.nom]