Salome HOME
b993b668e705505233f303964aef34440d73f2f3
[tools/eficas.git] / Noyau / N_MCSIMP.py
1 # coding=utf-8
2 # Copyright (C) 2007-2021   EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19
20
21 """
22     Ce module contient la classe MCSIMP qui sert à controler la valeur
23     d'un mot-clé simple par rapport à sa définition portée par un objet
24     de type ENTITE
25 """
26
27 from __future__ import absolute_import
28 from copy import copy
29
30 from Noyau.N_ASSD import ASSD
31 from Noyau.N_UserASSDMultiple import UserASSDMultiple
32 from Noyau.N_CO import CO
33 from . import N_OBJECT
34 from .N_CONVERT import ConversionFactory
35 from .N_types import forceList, isSequence
36
37
38 class MCSIMP(N_OBJECT.OBJECT):
39
40     """
41     """
42     nature = 'MCSIMP'
43
44     def __init__(self, val, definition, nom, parent,objPyxbDeConstruction):
45         """
46            Attributs :
47
48             - val : valeur du mot clé simple
49             - definition
50             - nom
51             - parent
52
53           Autres attributs :
54
55             - valeur : valeur du mot-clé simple en tenant compte de la valeur par défaut
56
57         """
58         #print (self, val, definition, nom, parent)
59         self.definition = definition
60         self.nom = nom
61         self.val = val
62         self.parent = parent
63         self.objPyxbDeConstruction = objPyxbDeConstruction
64         if parent:
65             self.jdc = self.parent.jdc
66             if self.jdc : self.cata = self.jdc.cata
67             else        : self.cata = None
68             self.niveau = self.parent.niveau
69             self.etape  = self.parent.etape
70         else:
71             # Le mot cle simple a été créé sans parent
72             # est-ce possible ?
73             print ('je suis dans le else sans parent du build')
74             self.jdc    = None
75             self.cata   = None
76             self.niveau = None
77             self.etape  = None
78         if self.definition.creeDesObjets :
79             if issubclass(self.definition.creeDesObjetsDeType, UserASSDMultiple) :
80                 self.convProto = ConversionFactory('UserASSDMultiple', self.definition.creeDesObjetsDeType)
81             else :
82                 self.convProto = ConversionFactory('UserASSD', self.definition.creeDesObjetsDeType)
83         else :
84             self.convProto = ConversionFactory('type', typ=self.definition.type)
85         self.valeur = self.getValeurEffective(self.val)
86         if self.definition.utiliseUneReference :
87             if self.valeur != None:
88                 if not type(self.valeur) in (list, tuple): self.valeur.ajoutUtilisePar(self)
89                 else :
90                     #PNPN --> chgt pour Vimmp
91                     for v in self.valeur :
92                         print (v, type(v))
93                         v.ajoutUtilisePar(self)
94                         #try : v.ajoutUtilisePar(self)
95                         #except : print ('il y a un souci ici', self.nom, self.valeur)
96         self.buildObjPyxb()
97         self.listeNomsObjsCrees = []
98
99     def getValeurEffective(self, val):
100         """
101             Retourne la valeur effective du mot-clé en fonction
102             de la valeur donnée. Defaut si val == None
103             Attention aux UserASSD et aux into (exple Wall gp de maille et 'Wall')
104         """
105         #print ('getValeurEffective ________________', val)
106         if (val is None and hasattr(self.definition, 'defaut')): val = self.definition.defaut
107         if self.definition.type[0] == 'TXM' and isinstance(val,str) : return val
108         if self.definition.creeDesObjets :
109             # isinstance(val, self.definition.creeDesObjetsDeType) ne fonctionne pas car il y a un avec cata devant et l autre non
110             if val == None : return val
111             if not isinstance(val,(list,tuple)) : valATraiter=[val,]
112             else : valATraiter=val
113             listeRetour=[]
114             for v in valATraiter:
115                 #print (v.__class__.__name__, self.definition.creeDesObjetsDeType.__name__)
116                 if  (not(v.__class__.__name__ == self.definition.creeDesObjetsDeType.__name__)) :
117                     if self.jdc != None and v in list(self.jdc.sdsDict.keys()): v=self.jdc.sdsDict[v]
118                     else : v=self.convProto.convert(v)
119                     if v.parent== None : v.initialiseParent(self)
120                     if issubclass(self.definition.creeDesObjetsDeType, UserASSDMultiple) :
121                         v.ajouteUnPere(self)
122                 else :
123                     if v.nom=='sansNom' :
124                         for leNom,laVariable in self.jdc.g_context.items():
125                             #print (leNom,laVariable)
126                             if id(laVariable) == id(v) and (leNom != 'sansNom'):
127                                 v.initialiseNom(leNom)
128                     if v.parent== None : v.initialiseParent(self)
129                     if issubclass(self.definition.creeDesObjetsDeType, UserASSDMultiple) :
130                         v.ajouteUnPere(self)
131                 listeRetour.append(v)
132             if isinstance(val,(list,tuple)) :newVal=listeRetour
133             else : newVal=listeRetour[0]
134             return newVal
135         if self.convProto:
136             val = self.convProto.convert(val)
137         return val
138
139     def creeUserASSDetSetValeur(self, val):
140         self.state='changed'
141         nomVal=val
142         if nomVal in self.jdc.sdsDict.keys():
143             if isinstance(self.jdc.sdsDict[nomVal],self.definition.creeDesObjetsDeType):
144                 if issubclass(self.definition.creeDesObjetsDeType, UserASSDMultiple) :
145                     p=self.parent
146                     while p in self.parent :
147                         if hasattr(p, 'listeDesReferencesCrees') : p.listeDesReferencesCrees.append(self.jdc.sdsDict[nomVal])
148                         else : p.listeDesReferencesCrees=[self.jdc.sdsDict[nomVal],]
149                         p=p.parent
150                         self.jdc.sdsDict[nomVal].ajouteUnPere(self)
151                         #return (1, 'reference ajoutee')
152                 else :
153                     return (0, 'concept non multiple deja reference')
154             else : return (0, 'concept d un autre type existe deja')
155         if self.convProto:
156             objVal = self.convProto.convert(nomVal)
157             objVal.initialiseNom(nomVal)
158             if objVal.parent== None : objVal.initialiseParent(self)
159             objVal.ajouteUnPere(self)
160             p=self.parent
161             while p in self.parent :
162                 print ('mise a jour de ',p)
163                 if hasattr(p, 'listeDesReferencesCrees') : p.listeDesReferencesCrees.append(objVal)
164                 else : p.listeDesReferencesCrees=[objVal,]
165                 p=p.parent
166         return (self.setValeur(objVal), 'reference creee')
167
168     def creeUserASSD(self, val):
169         self.state='changed'
170         nomVal=val
171         if nomVal in self.jdc.sdsDict.keys():
172             if isinstance(self.jdc.sdsDict[nomVal],self.definition.creeDesObjetsDeType):
173                 if issubclass(self.definition.creeDesObjetsDeType, UserASSDMultiple) :
174                     p=self.parent
175                     while p in self.parent :
176                         if hasattr(p, 'listeDesReferencesCrees') : p.listeDesReferencesCrees.append(self.jdc.sdsDict[nomVal])
177                         else : p.listeDesReferencesCrees=[self.jdc.sdsDict[nomVal],]
178                         p=p.parent
179                         self.jdc.sdsDict[nomVal].ajouteUnPere(self)
180                         return (1,self.jdc.sdsDict[nomVal], 'reference ajoutee')
181                 else : return (0, None, 'concept d un autre type existe deja')
182             else : return (0, None, 'concept d un autre type existe deja')
183         if self.convProto:
184             objVal = self.convProto.convert(nomVal)
185             objVal.initialiseNom(nomVal)
186             objVal.ajouteUnPere(self)
187         return (1, objVal, 'reference creee')
188
189     def rattacheUserASSD(self, objASSD):
190         if objASSD.parent== None : objASSD.initialiseParent(self)
191         p=self.parent
192         while p in self.parent :
193             if hasattr(p, 'listeDesReferencesCrees') : p.listeDesReferencesCrees.append(objASSD)
194             else : p.listeDesReferencesCrees=[objASSD,]
195             p=p.parent
196
197
198     def getValeur(self):
199         """
200             Retourne la "valeur" d'un mot-clé simple.
201             Cette valeur est utilisée lors de la création d'un contexte
202             d'évaluation d'expressions à l'aide d'un interpréteur Python
203         """
204         v = self.valeur
205         # Si singleton et max=1, on retourne la valeur.
206         # Si une valeur simple et max='**', on retourne un singleton.
207         # (si liste de longueur > 1 et max=1, on sera arrêté plus tard)
208         # Pour accepter les numpy.array, on remplace : "type(v) not in (list, tuple)"
209         # par "not has_attr(v, '__iter__')".
210         if v is None:
211             pass
212         elif isSequence(v) and len(v) == 1 and self.definition.max == 1:
213             v = v[0]
214         elif not isSequence(v) and self.definition.max != 1:
215             v = (v, )
216         # traitement particulier pour les complexes ('RI', r, i)
217         if 'C' in self.definition.type and self.definition.max != 1 and v != None and v[0] in ('RI', 'MP'):
218             v = (v, )
219         return v
220
221     def getVal(self):
222         """
223             Une autre méthode qui retourne une "autre" valeur du mot clé simple.
224             Elle est utilisée par la méthode getMocle
225         """
226         return self.valeur
227
228     def accept(self, visitor):
229         """
230            Cette methode permet de parcourir l'arborescence des objets
231            en utilisant le pattern VISITEUR
232         """
233         visitor.visitMCSIMP(self)
234
235     def copy(self):
236         """ Retourne une copie de self """
237         objet = self.makeobjet()
238         # il faut copier les listes et les tuples mais pas les autres valeurs
239         # possibles (réel,SD,...)
240         if type(self.valeur) in (list, tuple):
241             objet.valeur = copy(self.valeur)
242         else:
243             objet.valeur = self.valeur
244         objet.val = objet.valeur
245         return objet
246
247     def makeobjet(self):
248         return self.definition(val=None, nom=self.nom, parent=self.parent)
249
250     def reparent(self, parent):
251         """
252            Cette methode sert a reinitialiser la parente de l'objet
253         """
254         self.parent = parent
255         self.jdc = parent.jdc
256         self.etape = parent.etape
257
258     def getSd_utilisees(self):
259         """
260             Retourne une liste qui contient la ou les SD utilisée par self si c'est le cas
261             ou alors une liste vide
262         """
263         l = []
264         if isinstance(self.valeur, ASSD):
265             l.append(self.valeur)
266         elif type(self.valeur) in (list, tuple):
267             for val in self.valeur:
268                 if isinstance(val, ASSD):
269                     l.append(val)
270         return l
271
272     def getSd_mcs_utilisees(self):
273         """
274             Retourne la ou les SD utilisée par self sous forme d'un dictionnaire :
275               - Si aucune sd n'est utilisée, le dictionnaire est vide.
276               - Sinon, la clé du dictionnaire est le mot-clé simple ; la valeur est
277                 la liste des sd attenante.
278
279                 Exemple ::
280                         { 'VALE_F': [ <Cata.cata.fonction_sdaster instance at 0x9419854>,
281                                       <Cata.cata.fonction_sdaster instance at 0x941a204> ] }
282         """
283         l = self.getSd_utilisees()
284         dico = {}
285         if len(l) > 0:
286             dico[self.nom] = l
287         return dico
288
289
290     def getMcsWithCo(self, co):
291         """
292             Cette methode retourne l'objet MCSIMP self s'il a le concept co
293             comme valeur.
294         """
295         if co in forceList(self.valeur):
296             return [self, ]
297         return []
298
299     def getAllCo(self):
300         """
301             Cette methode retourne la liste de tous les concepts co
302             associés au mot cle simple
303         """
304         return [co for co in forceList(self.valeur)
305                 if isinstance(co, CO) and co.isTypCO()]
306
307     def supprime(self):
308         if not type(self.valeur) in (list, tuple): lesValeurs=(self.valeur,)
309         else : lesValeurs=self.valeur
310         if self.valeur == None or self.valeur == [] : lesValeurs=[]
311         for val in lesValeurs:
312             if self.definition.creeDesObjets : val.deleteReference(self)
313             else :
314                 if (hasattr (val, 'enleveUtilisePar')) : val.enleveUtilisePar(self)
315         N_OBJECT.OBJECT.supprime(self)
316
317     def getUserAssdPossible(self):
318         debug=False
319         if self.nom == 'ApplyOn' : debug = True
320         if debug : print ('____________', self, self.nom)
321         classeAChercher = self.definition.type
322         if debug : print ('____________', classeAChercher)
323         l=[]
324         dicoValeurs={}
325         d={}
326         if debug : print ('____________', self.definition.filtreVariables)
327         if self.definition.filtreVariables != None :
328             for (nomMC, Xpath) in self.definition.filtreVariables :
329                 if debug : print (nomMC, Xpath)
330                 if Xpath == None : dicoValeurs[nomMC] = getattr(self,nomMC)
331                 else :
332                     try: #if 1 :
333                         pereMC=eval(Xpath)
334                         if debug : print ('pereMC :',pereMC)
335                         if pereMC :
336                             exp=Xpath+'.getChild("'+nomMC+'")'
337                             leMotCle=eval(exp)
338                         else : leMotCle=None
339                         if debug : print ('leMotCle', leMotCle)
340                         if leMotCle :
341                             if leMotCle.val : dicoValeurs[nomMC]=leMotCle.val
342                             elif leMotCle.definition.max != 1 : dicoValeurs[nomMC] = []
343                             else : dicoValeurs[nomMC] = None
344                             if debug : print ('dicoValeurs', dicoValeurs)
345                         else :
346                         #PN PN est-ce sur ? sinon quoi None ou []
347                         # je pense que les 2 valeurs doivent être renseignees si le filtre depend de 2 valeurs
348                             return l
349                     except:
350                         return l
351
352
353         for k,v in self.parent.jdc.sdsDict.items():
354             if (isinstance(v, classeAChercher)) :
355                 if debug : print ('je traite', v)
356                 if self.definition.filtreExpression :
357                     if debug : print ('expression', self.definition.filtreExpression)
358                     if debug : 
359                        print (v.executeExpression(self.definition.filtreExpression ,dicoValeurs) )
360                     try :
361                         if v.executeExpression(self.definition.filtreExpression ,dicoValeurs) : l.append(v)
362                     except :
363                         print ('il faut comprendre except pour', self.nom)
364                         #print (self.nom)
365                         #print (self.parent.nom)
366                         #print (k,v)
367                 else : l.append(v)
368         return l