+# -*- coding: utf-8 -*-
+# CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
+# (AT YOUR OPTION) ANY LATER VERSION.
+#
+# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
+# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
+# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
"""
"""
# Modules Python
# Modules Eficas
import I_OBJECT
-from Noyau.N_ASSD import assd
+from Noyau.N_ASSD import ASSD
from Noyau.N_ETAPE import ETAPE
-from Noyau.N_CO import CO
from Noyau.N_Exception import AsException
from Extensions import commentaire,parametre,parametre_eval
self.niveau=self
self.params=[]
self.fonctions=[]
-
- def get_cmd(self,nomcmd):
- """
- Retourne l'objet de type COMMANDE de nom nomcmd
- """
- for cata in self.cata:
- if hasattr(cata,nomcmd):
- return getattr(cata,nomcmd)
+ self._etape_context=None
+ self.recorded_units={}
+ self.old_recorded_units={}
def get_sd_avant_du_bon_type(self,etape,types_permis):
"""
l=[]
for k,v in d.items():
if type(v) != types.InstanceType : continue
- if assd in types_permis or CO in types_permis :
- l.append(k)
- continue
- for type_ok in types_permis:
- if type_ok in ('R','I','C','TXM') and v in self.params : l.append(k)
- elif type_ok == 'R' and v.__class__.__name__ == 'reel' : l.append(k)
- elif type_ok == 'I' and v.__class__.__name__ == 'entier' : l.append(k)
- elif type_ok == 'C' and v.__class__.__name__ == 'complexe' : l.append(k)
- elif type_ok == 'TXM' and v.__class__.__name__ == 'chaine' : l.append(k)
- elif type(type_ok) != types.ClassType : continue
- elif v.__class__ == type_ok or issubclass(v.__class__,type_ok): l.append(k)
+ # On considère que seul assd indique un type quelconque pas CO
+ elif self.assd in types_permis :
+ l.append(k)
+ elif self.est_permis(v,types_permis):
+ l.append(k)
l.sort()
return l
+ def est_permis(self,v,types_permis):
+ for type_ok in types_permis:
+ if type_ok in ('R','I','C','TXM') and v in self.params :
+ return 1
+ elif type_ok == 'R' and v.__class__.__name__ == 'reel' :
+ return 1
+ elif type_ok == 'I' and v.__class__.__name__ == 'entier' :
+ return 1
+ elif type_ok == 'C' and v.__class__.__name__ == 'complexe' :
+ return 1
+ elif type_ok == 'TXM' and v.__class__.__name__ == 'chaine' :
+ return 1
+ elif type(type_ok) != types.ClassType :
+ continue
+ elif v.__class__ == type_ok or issubclass(v.__class__,type_ok):
+ return 1
+ return 0
+
def addentite(self,name,pos):
"""
Ajoute une entite :
if pos == None : pos = 0
self.etapes.insert(pos,objet)
self.editmode=0
+ self.reset_context()
self.active_etapes()
return objet
elif name == "PARAMETRE_EVAL":
if pos == None : pos = 0
self.etapes.insert(pos,objet)
self.editmode=0
+ self.reset_context()
self.active_etapes()
return objet
elif type(name)==types.InstanceType:
# existante (par copie donc)
# on est donc nécessairement en mode editeur ...
objet = name
- objet.jdc = objet.parent = self
- #XXX current_step n'existe plus. A priori le parent devrait etre self
- # ainsi que le step courant.
- #objet.parent = self.current_step
+ # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
+ objet.reparent(self)
self.set_current_step()
if isinstance(objet,ETAPE):
if objet.nom_niveau_definition == 'JDC':
objet.parent.dict_niveaux[objet.nom_niveau_definition].register(objet)
objet.niveau = objet.parent.dict_niveaux[objet.nom_niveau_definition]
self.etapes.insert(pos,objet)
+ # il faut vérifier que les concepts utilisés par objet existent bien
+ # à ce niveau d'arborescence
+ objet.verif_existence_sd()
self.active_etapes()
self.editmode=0
+ self.reset_context()
return objet
else :
# On veut ajouter une nouvelle commande
cmd=self.get_cmd(name)
# L'appel a make_objet n'a pas pour effet d'enregistrer l'étape
# auprès du step courant car editmode vaut 1
+ # Par contre elle a le bon parent grace a set_current_step
e=cmd.make_objet()
if pos == None : pos = 0
self.etapes.insert(pos,e)
self.reset_current_step()
self.editmode=0
+ self.reset_context()
self.active_etapes()
return e
+ except AsException,e:
+ self.reset_current_step()
+ self.editmode=0
+ raise AsException("Impossible d ajouter la commande "+name + '\n' +str(e))
except:
traceback.print_exc()
self.reset_current_step()
def get_sd_avant_etape(self,nom_sd,etape):
return self.get_contexte_avant(etape).get(nom_sd,None)
- def get_sd_apres_etape(self,nom_sd,etape):
+ def get_sd_apres_etape_avec_detruire(self,nom_sd,sd,etape,avec='non'):
+ """
+ Cette méthode retourne la SD sd de nom nom_sd qui est éventuellement
+ définie apres etape en tenant compte des concepts detruits
+ Si avec vaut 'non' exclut etape de la recherche
+ """
+ ietap=self.etapes.index(etape)
+ if avec == 'non':ietap=ietap+1
+ d={nom_sd:sd}
+ for e in self.etapes[ietap:]:
+ if e.isactif():
+ e.update_context(d)
+ autre_sd=d.get(nom_sd,None)
+ if autre_sd is None:
+ # Le concept a ete detruit
+ return None
+ if autre_sd is not sd :
+ # L'etape produit un concept de meme nom
+ if hasattr(e,'reuse') and e.reuse == autre_sd:
+ # Le concept etant reutilise, on interrompt la recherche.
+ # On considere qu'il n'y a pas de nouveau concept defini
+ # meme si dans les etapes suivantes le concept est detruit
+ # et un concept de meme nom créé.
+ return None
+ else:
+ # Le concept est produit par l'etape
+ return autre_sd
+ # On n'a rien trouve. Pas de concept de nom nom_sd
+ return None
+
+ def get_sd_apres_etape(self,nom_sd,etape,avec='non'):
"""
Cette méthode retourne la SD de nom nom_sd qui est éventuellement
- définie apres etape
+ définie apres etape
+ Si avec vaut 'non' exclut etape de la recherche
"""
ietap=self.etapes.index(etape)
- for e in self.etapes[ietap+1:]:
+ if avec == 'non':ietap=ietap+1
+ for e in self.etapes[ietap:]:
sd=e.get_sdprods(nom_sd)
if sd:
if hasattr(e,'reuse'):
return sd
return None
- def get_sd_autour_etape(self,nom_sd,etape):
+ def get_sd_autour_etape(self,nom_sd,etape,avec='non'):
"""
Fonction: retourne la SD de nom nom_sd qui est éventuellement
- définie avant ou apres etape
+ définie avant ou apres etape
Permet de vérifier si un concept de meme nom existe dans le périmètre
d'une étape
+ Si avec vaut 'non' exclut etape de la recherche
"""
sd=self.get_sd_avant_etape(nom_sd,etape)
if sd:return sd
- return self.get_sd_apres_etape(nom_sd,etape)
+ return self.get_sd_apres_etape(nom_sd,etape,avec)
+
+ def get_contexte_apres(self,etape):
+ """
+ Retourne le dictionnaire des concepts connus apres etape
+ On tient compte des commandes qui modifient le contexte
+ comme DETRUIRE ou les macros
+ Si etape == None, on retourne le contexte en fin de JDC
+ """
+ if not etape: return self.get_contexte_avant(etape)
+
+ d=self.get_contexte_avant(etape)
+ if etape.isactif():etape.update_context(d)
+ self.index_etape_courante=self.index_etape_courante+1
+ return d
def active_etapes(self):
"""
"""
Cette methode a pour fonction de supprimer une étape dans
un jeu de commandes
+ Retourne 1 si la suppression a pu être effectuée,
+ Retourne 0 dans le cas contraire
"""
self.init_modif()
+ # On memorise le contexte avant l'etape a supprimer
+ d=self.get_contexte_avant(etape)
+ index_etape=self.etapes.index(etape)
+
self.etapes.remove(etape)
if etape.niveau is not self:
# Dans ce cas l'étape est enregistrée dans un niveau
etape.supprime_sdprods()
self.active_etapes()
- def del_sdprod(self,sd):
- """
- Supprime la SD sd de la liste des sd et des dictionnaires de contexte
- """
- if sd in self.sds : self.sds.remove(sd)
- if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
-
- def delete_concept(self,sd):
- """
- Inputs :
- sd=concept detruit
- Fonction :
- Mettre a jour les etapes du JDC suite à la disparition du
- concept sd
- Seuls les mots cles simples MCSIMP font un traitement autre
- que de transmettre aux fils
- """
- for etape in self.etapes :
- etape.delete_concept(sd)
+ # Apres suppression de l'etape il faut controler que les etapes
+ # suivantes ne produisent pas des concepts DETRUITS dans op_init de etape
+ for e in self.etapes[index_etape:]:
+ e.control_sdprods(d)
+
+ self.reset_context()
+ self.fin_modif()
+ return 1
def analyse(self):
self.compile()
self.exec_compile()
self.active_etapes()
- def register(self,etape):
- """
- Cette méthode ajoute etape dans la liste
- des etapes self.etapes et retourne l identificateur d'étape
- fourni par l appel a g_register
- A quoi sert editmode ?
- - Si editmode vaut 1, on est en mode edition de JDC. On cherche
- à enregistrer une étape que l'on a créée avec eficas (en passant
- par addentite) auquel cas on ne veut récupérer que son numéro
- d'enregistrement et c'est addentité qui l'enregistre dans
- self.etapes à la bonne place...
- - Si editmode vaut 0, on est en mode relecture d'un fichier de
- commandes et on doit enregistrer l'étape à la fin de self.etapes
- (dans ce cas l'ordre des étapes est bien l'ordre chronologique
- de leur création )
- """
- if not self.editmode:
- self.etapes.append(etape)
- else:
- pass
- return self.g_register(etape)
-
def register_parametre(self,param):
"""
Cette méthode sert à ajouter un paramètre dans la liste des paramètres
"""
self.params.append(param)
+ def register_fonction(self,fonction):
+ """
+ Cette méthode sert à ajouter une fonction dans la liste des fonctions
+ """
+ self.fonctions.append(fonction)
+
def delete_param(self,param):
"""
Supprime le paramètre param de la liste des paramètres
nom = form.nom
if not nom : continue
if d.has_key(nom): l_fonctions.append(form.get_formule())
+
+ # on ajoute les concepts produits par DEFI_VALEUR
+ # XXX On pourrait peut etre faire plutot le test sur le type
+ # de concept : entier, reel, complexe, etc.
+ for k,v in d.items():
+ if hasattr(v,'etape') and v.etape.nom in ('DEFI_VALEUR',):
+ l_constantes.append(k)
+
# on retourne les deux listes
return l_constantes,l_fonctions
if self.appli:
self.appli.send_message(message)
-#XXX ne semble pas servir pour JDC
-# def reevalue_sd_jdc(self):
- #"""
- #Avec la liste des SD qui ont été supprimées, propage la disparition de ces
- #SD dans toutes les étapes et descendants
- #"""
- #l_sd = self.diff_contextes()
- #if len(l_sd) == 0 : return
- #for sd in l_sd:
- #self.jdc.delete_concept(sd)
-
def init_modif(self):
"""
Méthode appelée au moment où une modification va être faite afin de
self.state = 'modified'
def fin_modif(self):
+ self.isvalid()
pass
def get_liste_mc_inconnus(self):
if l : l_mc.extend(l)
return l_mc
- def get_file(self,unite=None,fic_origine=''):
+ def get_genealogie(self):
+ """
+ Retourne la liste des noms des ascendants de l'objet self
+ jusqu'à la première ETAPE parent.
+ """
+ return []
+
+ def set_etape_context(self,etape):
+ """
+ Positionne l'etape qui sera utilisee dans NommerSdProd pour
+ decider si le concept passé pourra etre nommé
+ """
+ self._etape_context=etape
+
+ def reset_context(self):
+ """
+ Cette methode reinitialise le contexte glissant pour pouvoir
+ tenir compte des modifications de l'utilisateur : création
+ de commandes, nommage de concepts, etc.
+ """
+ self.current_context={}
+ self.index_etape_courante=0
+
+ def del_sdprod(self,sd):
+ """
+ Supprime la SD sd de la liste des sd et des dictionnaires de contexte
+ """
+ if sd in self.sds : self.sds.remove(sd)
+ if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
+ if self.sds_dict.has_key(sd.nom) : del self.sds_dict[sd.nom]
+
+ def del_param(self,param):
+ """
+ Supprime le paramètre param de la liste des paramètres
+ et du contexte gobal
+ """
+ if param in self.params : self.params.remove(param)
+ if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
+
+ def del_fonction(self,fonction):
+ """
+ Supprime la fonction fonction de la liste des fonctions
+ et du contexte gobal
+ """
+ if fonction in self.fonctions : self.fonctions.remove(fonction)
+ if self.g_context.has_key(fonction.nom) : del self.g_context[fonction.nom]
+
+ def append_sdprod(self,sd):
+ """
+ Ajoute la SD sd à la liste des sd en vérifiant au préalable qu'une SD de
+ même nom n'existe pas déjà
+ """
+ if sd == None or sd.nom == None:return
+
+ o=self.sds_dict.get(sd.nom,None)
+ if isinstance(o,ASSD):
+ raise AsException("Nom de concept deja defini : %s" % sd.nom)
+ self.sds_dict[sd.nom]=sd
+ self.g_context[sd.nom] = sd
+ if sd not in self.sds : self.sds.append(sd)
+
+ def append_param(self,param):
+ """
+ Ajoute le paramètre param à la liste des params
+ et au contexte global
+ """
+ # il faudrait vérifier qu'un paramètre de même nom n'existe pas déjà !!!
+ if param not in self.params : self.params.append(param)
+ self.g_context[param.nom]=param
+
+ def append_fonction(self,fonction):
+ """
+ Ajoute la fonction fonction à la liste des fonctions
+ et au contexte global
+ """
+ # il faudrait vérifier qu'une fonction de même nom n'existe pas déjà !!!
+ if fonction not in self.fonctions : self.fonctions.append(fonction)
+ self.g_context[fonction.nom]=fonction
+
+ def delete_concept(self,sd):
+ """
+ Inputs :
+ - sd=concept detruit
+ Fonction :
+ Mettre a jour les etapes du JDC suite à la disparition du
+ concept sd
+ Seuls les mots cles simples MCSIMP font un traitement autre
+ que de transmettre aux fils
+ """
+ for etape in self.etapes :
+ etape.delete_concept(sd)
+
+ def replace_concept_after_etape(self,etape,old_sd,sd):
+ """
+ Met à jour les étapes du JDC qui sont après etape en fonction
+ du remplacement du concept sd
+ """
+ index = self.etapes.index(etape)+1
+ if index == len(self.etapes) :
+ return # etape est la dernière étape du jdc ...on ne fait rien !
+ for child in self.etapes[index:]:
+ child.replace_concept(old_sd,sd)
+
+ def dump_state(self):
+ print "dump_state"
+ print "JDC.state: ",self.state
+ for etape in self.etapes :
+ print etape.nom+".state: ",etape.state
+
+ def change_unit(self,unit,etape,old_unit):
+ if self.recorded_units.has_key(old_unit):del self.recorded_units[old_unit]
+ self.record_unit(unit,etape)
+
+ def record_unit(self,unit,etape):
+ """Enregistre les unites logiques incluses et les infos relatives a l'etape"""
+ if unit is None:
+ # Cas de POURSUITE
+ self.recorded_units[None]=(etape.fichier_ini ,etape.fichier_text,etape.recorded_units)
+ else:
+ self.recorded_units[unit]=(etape.fichier_ini ,etape.fichier_text,etape.recorded_units)
+
+#ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
+ def register(self,etape):
+ """
+ Cette méthode ajoute etape dans la liste
+ des etapes self.etapes et retourne l identificateur d'étape
+ fourni par l appel a g_register
+
+ A quoi sert editmode ?
+ - Si editmode vaut 1, on est en mode edition de JDC. On cherche
+ à enregistrer une étape que l'on a créée avec eficas (en passant
+ par addentite) auquel cas on ne veut récupérer que son numéro
+ d'enregistrement et c'est addentité qui l'enregistre dans
+ self.etapes à la bonne place...
+ - Si editmode vaut 0, on est en mode relecture d'un fichier de
+ commandes et on doit enregistrer l'étape à la fin de self.etapes
+ (dans ce cas l'ordre des étapes est bien l'ordre chronologique
+ de leur création )
+ """
+ if not self.editmode:
+ self.etapes.append(etape)
+ else:
+ pass
+ return self.g_register(etape)
+
+#ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
+ def NommerSdprod(self,sd,sdnom,restrict='non'):
"""
- Retourne le nom du fichier correspondant à un numero d'unité
- logique (entier) ainsi que le source contenu dans le fichier
+ Nomme la SD apres avoir verifie que le nommage est possible :
+ nom non utilise
+ Si le nom est deja utilise, leve une exception
+ Met le concept créé dans le concept global g_context
"""
- if self.appli :
- # Si le JDC est relié à une application maitre, on délègue la recherche
- file,text = self.appli.get_file(unite,fic_origine)
+ # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
+ # Le dictionnaire g_context ne représente pas le contexte
+ # effectif avant une étape.
+ # Il faut utiliser get_contexte_avant avec indication de l'étape
+ # traitée.
+ # Cette etape est indiquee par l'attribut _etape_context qui a ete
+ # positionné préalablement par un appel à set_etape_context
+
+ if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
+
+ if self._etape_context:
+ o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
else:
- file = None
- if unite != None:
- if os.path.exists("fort."+str(unite)):
- file= "fort."+str(unite)
- if file == None :
- raise AsException("Impossible de trouver le fichier correspondant \
- a l unite %s" % unite)
- if not os.path.exists(file):
- raise AsException("%s n'est pas un fichier existant" % unite)
- fproc=open(file,'r')
- text=fproc.read()
- fproc.close()
- text=string.replace(text,'\r\n','\n')
- linecache.cache[file]=0,0,string.split(text,'\n'),file
- return file,text
+ o=self.sds_dict.get(sdnom,None)
+
+ if isinstance(o,ASSD):
+ raise AsException("Nom de concept deja defini : %s" % sdnom)
+
+ # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
+ # Ajoute a la creation (appel de reg_sd).
+ self.sds_dict[sdnom]=sd
+ sd.nom=sdnom
+
+ # En plus si restrict vaut 'non', on insere le concept dans le contexte du JDC
+ if restrict == 'non':
+ self.g_context[sdnom]=sd
+
+#ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
+ def delete_concept_after_etape(self,etape,sd):
+ """
+ Met à jour les étapes du JDC qui sont après etape en fonction
+ de la disparition du concept sd
+ """
+ index = self.etapes.index(etape)+1
+ if index == len(self.etapes) :
+ return # etape est la dernière étape du jdc ...on ne fait rien !
+ for child in self.etapes[index:]:
+ child.delete_concept(sd)
+
+#ATTENTION SURCHARGE : les methodes ci-dessous surchargent des methodes de Noyau et Validation : a reintegrer