Salome HOME
bf37b0b8f34691a1a0f5e95fe61d9d8972fee849
[modules/kernel.git] / src / KERNEL_PY / __init__.py
1 #  -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
3 #
4 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
5 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20 #
21 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #
23
24 #  File   : salome.py renamed as __init__.py for python packaging (gboulant)
25 #  Author : Paul RASCLE, EDF
26 #  Module : SALOME
27 #
28 """ 
29 Module salome gives access to Salome resources.
30
31 variables:
32
33   - salome.orb             : CORBA
34   - salome.naming_service  : instance of naming Service class
35       - methods:
36           - Resolve(name)  : find a CORBA object (ior) by its pathname
37           - Register(name) : register a CORBA object under a pathname
38
39   - salome.lcc             : instance of lifeCycleCORBA class
40       - methods:
41           - FindOrLoadComponent(server,name) :
42                            obtain an Engine (CORBA object)
43                            or launch the Engine if not found,
44                            with a Server name and an Engine name
45
46   - salome.sg              : salome object to communicate with the graphical user interface (if any)
47       - methods:
48          - updateObjBrowser():
49
50          - SelectedCount():      returns number of selected objects
51          - getSelected(i):       returns entry of selected object number i
52          - getAllSelected():     returns list of entry of selected objects
53          - AddIObject(Entry):    select an existing Interactive object
54          - RemoveIObject(Entry): remove object from selection
55          - ClearIObjects():      clear selection
56
57          - Display(*Entry):
58          - DisplayOnly(Entry):
59          - Erase(Entry):
60          - DisplayAll():
61          - EraseAll():
62
63          - IDToObject(Entry):    returns CORBA reference from entry
64
65   - salome.myStudyName     : active Study Name
66   - salome.myStudy         : the active Study itself (CORBA ior)
67       - methods : defined in SALOMEDS.idl
68
69 """
70 ## @package salome
71 # Module salome gives access to Salome resources.
72 #
73 #  \param salome.orb             : CORBA orb object
74 #  \param salome.naming_service  : instance of naming Service class (SALOME_NamingServicePy::SALOME_NamingServicePy_i)
75 #  \param salome.lcc             : instance of lifeCycleCORBA class (SALOME_LifeCycleCORBA)
76 #  \param salome.sg              : Salome object to communicate with the graphical user interface, if running (see interface in salome_iapp::SalomeOutsideGUI)
77 #  \param salome.myStudyName     : active Study Name
78 #  \param salome.myStudy         : the active Study (interface SALOMEDS::Study)
79
80 #
81 # ==========================================================================
82 #
83 # The function extend_path is used here to aggregate in a single
84 # virtual python package all the python sub-packages embedded in each
85 # SALOME modules (python "namespace" pattern).
86 #
87 ROOT_PYTHONPACKAGE_NAME="salome"
88 #
89 # This root package name is expected to be found as a directory in
90 # some paths of the sys.path variable, especially the paths
91 # <MODULE_ROOT_DIR>/lib/pythonX.Y/site-packages/salome where are
92 # installed the python files. These paths are theorically appended by
93 # the SALOME main runner and should be in the sys.path at this point
94 # of the application. The extend_path is looking then for directories
95 # of the type:
96 #
97 # <MODULE_ROOT_DIR>/lib/pythonX.Y/site-packages/salome/<ROOT_PYTHONPACKAGE_NAME>
98 #
99 # And append them to the sys.path. These directories are supposed to
100 # be the pieces to be aggregated as a single virtual python package.
101 #
102 import os, sys
103 from salome_utils import verbose
104
105 MATCH_ENDING_PATTERN="site-packages" + os.path.sep + "salome"
106
107 def extend_path(pname):
108     for dir in sys.path:
109         if not isinstance(dir, str) or not os.path.isdir(dir) or not dir.endswith(MATCH_ENDING_PATTERN):
110             continue
111         subdir = os.path.join(dir, pname)
112         # XXX This may still add duplicate entries to path on
113         # case-insensitive filesystems
114         if os.path.isdir(subdir) and subdir not in __path__:
115             if verbose(): print("INFO - The directory %s is appended to sys.path" % subdir)
116             __path__.append(subdir)
117
118 extend_path(ROOT_PYTHONPACKAGE_NAME)
119 # ==========================================================================
120 #
121
122 from salome_kernel import *
123 from salome_study import *
124 from salome_iapp import *
125 import salome_study
126
127 #
128 # The next block is workaround for the problem of shared symbols loading for the extension modules (e.g. SWIG-generated)
129 # that causes RTTI unavailable in some cases. To solve this problem, sys.setdlopenflags() function is used.
130 # Depending on the Python version and platform, the dlopen flags can be defined in the dl, DLFUN or ctypes module.
131
132 import sys
133 flags = None
134 if not flags:
135     try:
136         # dl module can be unavailable
137         import dl
138         flags = dl.RTLD_NOW | dl.RTLD_GLOBAL
139     except:
140         pass
141     pass
142 if not flags:
143     try:
144         # DLFCN module can be unavailable
145         import DLFCN
146         flags = DLFCN.RTLD_NOW | DLFCN.RTLD_GLOBAL
147     except:
148         pass
149     pass
150 if not flags:
151     try:
152         # ctypes module can be unavailable
153         import ctypes
154         flags = ctypes.RTLD_GLOBAL
155     except:
156         pass
157     pass
158
159 # Disable -> bug with scipy, seems very dangerous to do that
160 #if flags:
161 #    sys.setdlopenflags(flags)
162 #    pass
163
164 orb, lcc, naming_service, cm, sg, esm, dsm, modulcat = None,None,None,None,None,None,None,None
165 myStudy, myStudyName = None,None
166
167 salome_initial=True
168
169 __EMB_SERVANT_ENV_VAR_NAME = "SALOME_EMB_SERVANT"
170
171 def standalone():
172     import os
173     os.environ[__EMB_SERVANT_ENV_VAR_NAME] = "1"
174
175 def salome_init(path=None, embedded=False):
176     import os
177     if __EMB_SERVANT_ENV_VAR_NAME in os.environ:
178         salome_init_without_session()
179     else:
180         import KernelBasis
181         if KernelBasis.getSSLMode():
182             salome_init_without_session()
183         else:
184             salome_init_with_session(path, embedded)
185
186 class StandAloneLifecyle:
187     def __init__(self, containerManager, resourcesManager):
188         self._cm = containerManager
189         self._rm = resourcesManager
190
191     def FindOrLoadComponent(self,contName,moduleName):
192         global orb
193         import importlib
194         builder_name = moduleName + "_SalomeSessionless"
195         moduleObj = importlib.import_module(builder_name)
196         result, orb = moduleObj.buildInstance(orb)
197         return result
198         #raise RuntimeError("Undealed situation cont = {} module = {}".format(contName,moduleName))
199
200     def getContainerManager(self):
201       return self._cm
202
203     def getResourcesManager(self):
204       return self._rm
205
206 def salome_init_without_session():
207     global lcc,naming_service,myStudy,orb,modulcat,sg,cm,dsm
208     import KernelBasis
209     KernelBasis.setSSLMode(True)
210     import KernelDS
211     myStudy = KernelDS.myStudy()
212     import CORBA
213     orb=CORBA.ORB_init([''])
214     import KernelModuleCatalog
215     import SALOME_ModuleCatalog
216     from salome_kernel import list_of_catalogs_regarding_environement
217     modulcat = KernelModuleCatalog.myModuleCatalog( list_of_catalogs_regarding_environement() )
218     import KernelLauncher
219     from NamingService import NamingService
220     cm = KernelLauncher.myContainerManager()
221     lcc = StandAloneLifecyle(cm, KernelLauncher.myResourcesManager())
222     # activate poaManager to accept co-localized CORBA calls.
223     poa = orb.resolve_initial_references("RootPOA")
224     poaManager = poa._get_the_POAManager()
225     poaManager.activate()
226     sg = SalomeOutsideGUI()
227     salome_study_init_without_session()
228     naming_service = NamingService()
229     from KernelSDS import GetDSMInstance
230     dsm = GetDSMInstance()
231
232 def salome_init_with_session(path=None, embedded=False):
233     """
234     Performs only once SALOME general purpose initialisation for scripts.
235     Provides:
236     orb             reference to CORBA
237     lcc             a LifeCycleCorba instance
238     naming_service  a naming service instance
239     cm              reference to the container manager
240     esm             reference to external server manager
241     dsm             reference to shared dataserver manager
242     modulcat        reference to modulecatalog instance
243     sg              access to SALOME GUI (when linked with IAPP GUI)
244     myStudy         active study itself (CORBA reference)
245     myStudyName     active study name
246     """
247     global salome_initial
248     global orb, lcc, naming_service, cm, esm, dsm, modulcat
249     global sg
250     global myStudy, myStudyName
251     import KernelBasis
252     KernelBasis.setSSLMode(False)
253     try:
254         if salome_initial:
255             salome_initial=False
256             sg = salome_iapp_init(embedded)
257             orb, lcc, naming_service, cm, esm, dsm, modulcat = salome_kernel_init()
258             myStudy, myStudyName = salome_study_init(path)
259             pass
260         pass
261     except RuntimeError as inst:
262         # wait a little to avoid trace mix
263         import time
264         time.sleep(0.2)
265         x = inst
266         print("salome.salome_init():", x)
267         print("""
268         ============================================
269         May be there is no running SALOME session
270         salome.salome_init() is intended to be used
271         within an already running session
272         ============================================
273         """)
274         raise
275     
276 def salome_close():
277     global salome_initial, myStudy, myStudyName
278     try:
279         # study can be clear either from GUI or directly with salome.myStudy.Clear()
280         myStudy.Clear()
281     except:
282         pass
283     salome_initial=True
284     salome_iapp_close()
285     salome_study_close()
286     myStudy, myStudyName = None, None
287     import KernelDS
288     KernelDS.KillGlobalSessionInstance()
289     pass
290
291 def salome_NS():
292     import CORBA
293     import CosNaming
294     orb = CORBA.ORB_init()
295     ns0 = orb.resolve_initial_references("NameService")
296     return ns0._narrow(CosNaming.NamingContext)
297
298 def salome_walk_on_containers(ns,root):
299     import CosNaming
300     it = ns.list(0)[1]
301     if not it:
302         return
303     cont = True
304     while cont:
305         cont,obj = it.next_one()
306         if cont:
307             if obj.binding_name[0].kind == "object":
308                 import Engines
309                 corbaObj = ns.resolve(obj.binding_name)
310                 if isinstance(corbaObj,Engines._objref_Container):
311                     yield corbaObj,(root,obj.binding_name[0].id)
312             else:
313                 father = ns.resolve([obj.binding_name[0]])
314                 for elt,elt2 in salome_walk_on_containers(father,root+[obj.binding_name[0].id]):
315                     yield elt,elt2
316             pass
317         pass
318     pass
319
320 def salome_shutdown_containers():
321     salome_init()
322     ns=salome_NS()
323     li = [elt for elt in salome_walk_on_containers(ns,[""])]
324     print("Number of containers in NS : {}".format(len(li)))
325     for cont,(root,cont_name) in li:
326         try:
327             cont.Shutdown()
328         except:
329             pass
330         ref_in_ns = "/".join(root+[cont_name])
331         naming_service.Destroy_Name(ref_in_ns)
332     print("Number of containers in NS after clean : {}".format( len( list(salome_walk_on_containers(ns,[""])) )))
333
334
335 #to expose all objects to pydoc
336 __all__=dir()