]> SALOME platform Git repositories - modules/kernel.git/blob - src/KERNEL_PY/__init__.py
Salome HOME
d2be57dfc30154a84127bf78a2d12c67f7a4737a
[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 Exception:
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 Exception:
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 Exception:
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 def standalone():
170     pass
171
172 def withServers():
173     import KernelBasis
174     KernelBasis.setSSLMode(False)
175
176 def salome_init(path=None, embedded=False, iorfakensfile=None):
177     """
178     :param iorfakensfile: filename inside which IOR of fake NS will be written
179     """
180     import KernelBasis
181     if KernelBasis.getSSLMode():
182         if KernelBasis.getIOROfEmbeddedNS() == "":
183             salome_init_without_session(path, embedded, iorfakensfile)
184         else:
185             salome_init_without_session_attached(path, embedded)
186     else:
187         salome_init_with_session(path, embedded)
188
189 def salome_init_without_session_common(path=None, embedded=False):
190     from ORBConfigFile import writeORBConfigFileSSL
191     OMNIORB_USER_PATH = "OMNIORB_USER_PATH"
192     def RemoveOmniorbConfigFile():
193         import os
194         if "OMNIORB_CONFIG" in os.environ:
195             fileToRemove = os.environ["OMNIORB_CONFIG"]
196             if os.path.exists(fileToRemove):
197                 os.unlink(fileToRemove)
198
199     if OMNIORB_USER_PATH in os.environ:
200         import atexit
201         writeORBConfigFileSSL(os.environ[OMNIORB_USER_PATH],kwargs={"with_pid":True})
202         atexit.register(RemoveOmniorbConfigFile)
203
204     global lcc,naming_service,myStudy,orb,modulcat,sg
205     import KernelBasis
206     KernelBasis.setSSLMode(True)
207     import KernelDS
208     myStudy = KernelDS.myStudy()
209     import CORBA
210     orb=CORBA.ORB_init([''])
211     import KernelModuleCatalog
212     import SALOME_ModuleCatalog
213     from salome_kernel import list_of_catalogs_regarding_environement
214     modulcat = KernelModuleCatalog.myModuleCatalog( list_of_catalogs_regarding_environement() )
215     #
216     poa = orb.resolve_initial_references("RootPOA")
217     poaManager = poa._get_the_POAManager()
218     poaManager.activate()
219     #
220     sg = salome_iapp_init(embedded)
221     salome_study_init_without_session(path)
222     #
223     from NamingService import NamingService
224     naming_service = NamingService()
225
226 def salome_init_without_session(path=None, embedded=False, iorfakensfile=None):
227     salome_init_without_session_common(path,embedded)
228     global lcc,cm,dsm,esm
229     import KernelLauncher
230     cm = KernelLauncher.myContainerManager()
231     from LifeCycleCORBA import LifeCycleCORBASSL
232     lcc = LifeCycleCORBASSL()
233     # create a FactoryServer Container servant
234     import KernelContainer
235     KernelContainer.myContainer()
236     # activate poaManager to accept co-localized CORBA calls.
237     from KernelSDS import GetDSMInstance
238     import sys
239     if hasattr(sys, 'argv'):
240       argv = sys.argv
241     else:
242       argv = ['']
243     dsm = GetDSMInstance(argv)
244     # esm inherits from SALOME_CPythonHelper singleton already initialized by GetDSMInstance
245     # esm inherits also from SALOME_ResourcesManager creation/initialization (concerning SingleThreadPOA POA) when KernelLauncher.GetContainerManager() has been called
246     esm = KernelLauncher.GetExternalServer()
247     #
248     import KernelLogger
249     naming_service.Register(KernelLogger.myLogger(),"/Logger")
250     #
251     from NamingService import NamingService
252     if iorfakensfile is not None:
253         with open(iorfakensfile,"w") as iorfakensf:
254             iorfakensf.write(NamingService.IOROfNS())
255     
256 def salome_init_without_session_attached(path=None, embedded=False):
257     """
258     Configuration SSL inside a python interpretor launched in the SALOME_Container_No_NS_Serv.
259     In this configuration, 
260     """
261     salome_init_without_session_common(path,embedded)
262     global lcc,cm,dsm,esm
263     import CORBA
264     orb=CORBA.ORB_init([''])
265     import Engines
266     import KernelBasis
267     nsAbroad = orb.string_to_object( KernelBasis.getIOROfEmbeddedNS() )
268     import SALOME
269     CM_NAME_IN_NS = "/ContainerManager"
270     cm = orb.string_to_object( nsAbroad.Resolve(CM_NAME_IN_NS).decode() )
271     naming_service.Register(cm,CM_NAME_IN_NS)
272     RM_NAME_IN_NS = "/ResourcesManager"
273     rm = orb.string_to_object( nsAbroad.Resolve(RM_NAME_IN_NS).decode() )
274     naming_service.Register(rm,RM_NAME_IN_NS)
275     #
276     from LifeCycleCORBA import LifeCycleCORBASSL
277     lcc = LifeCycleCORBASSL()
278     DSM_NAME_IN_NS = "/DataServerManager"
279     dsm = orb.string_to_object( nsAbroad.Resolve(DSM_NAME_IN_NS).decode() )
280     naming_service.Register(dsm,DSM_NAME_IN_NS)
281     #
282     ESM_NAME_IN_NS = "/ExternalServers"
283     esm = orb.string_to_object( nsAbroad.Resolve(ESM_NAME_IN_NS).decode() )
284     naming_service.Register(esm,ESM_NAME_IN_NS)
285
286 def salome_init_with_session(path=None, embedded=False):
287     """
288     Performs only once SALOME general purpose initialisation for scripts.
289     Provides:
290     orb             reference to CORBA
291     lcc             a LifeCycleCorba instance
292     naming_service  a naming service instance
293     cm              reference to the container manager
294     esm             reference to external server manager
295     dsm             reference to shared dataserver manager
296     modulcat        reference to modulecatalog instance
297     sg              access to SALOME GUI (when linked with IAPP GUI)
298     myStudy         active study itself (CORBA reference)
299     myStudyName     active study name
300     """
301     global salome_initial
302     global orb, lcc, naming_service, cm, esm, dsm, modulcat
303     global sg
304     global myStudy, myStudyName
305     import KernelBasis
306     KernelBasis.setSSLMode(False)
307     try:
308         if salome_initial:
309             salome_initial=False
310             sg = salome_iapp_init(embedded)
311             orb, lcc, naming_service, cm, esm, dsm, modulcat = salome_kernel_init()
312             myStudy, myStudyName = salome_study_init(path)
313             pass
314         pass
315     except RuntimeError as inst:
316         # wait a little to avoid trace mix
317         import time
318         time.sleep(0.2)
319         x = inst
320         print("salome.salome_init():", x)
321         print("""
322         ============================================
323         May be there is no running SALOME session
324         salome.salome_init() is intended to be used
325         within an already running session
326         ============================================
327         """)
328         raise
329     
330 def salome_close():
331     global salome_initial, myStudy, myStudyName
332     try:
333         # study can be clear either from GUI or directly with salome.myStudy.Clear()
334         myStudy.Clear()
335     except Exception:
336         pass
337     salome_initial=True
338     salome_iapp_close()
339     salome_study_close()
340     myStudy, myStudyName = None, None
341     import KernelBasis
342     if KernelBasis.getSSLMode() and not KernelBasis.getGUIMode():
343         import KernelDS
344         KernelDS.KillGlobalSessionInstance()
345         import KernelSDS
346         KernelSDS.KillCPythonHelper()
347     pass
348
349 def salome_NS():
350     import CORBA
351     import CosNaming
352     orb = CORBA.ORB_init()
353     ns0 = orb.resolve_initial_references("NameService")
354     return ns0._narrow(CosNaming.NamingContext)
355
356 def salome_walk_on_containers(ns,root):
357     import CosNaming
358     it = ns.list(0)[1]
359     if not it:
360         return
361     cont = True
362     while cont:
363         cont,obj = it.next_one()
364         if cont:
365             if obj.binding_name[0].kind == "object":
366                 import Engines
367                 corbaObj = ns.resolve(obj.binding_name)
368                 if isinstance(corbaObj,Engines._objref_Container):
369                     yield corbaObj,(root,obj.binding_name[0].id)
370             else:
371                 father = ns.resolve([obj.binding_name[0]])
372                 for elt,elt2 in salome_walk_on_containers(father,root+[obj.binding_name[0].id]):
373                     yield elt,elt2
374             pass
375         pass
376     pass
377
378 def salome_shutdown_containers_with_session():
379     salome_init()
380     ns=salome_NS()
381     li = [elt for elt in salome_walk_on_containers(ns,[""])]
382     print("Number of containers in NS : {}".format(len(li)))
383     for cont,(root,cont_name) in li:
384         try:
385             cont.Shutdown()
386         except Exception:
387             pass
388         ref_in_ns = "/".join(root+[cont_name])
389         naming_service.Destroy_Name(ref_in_ns)
390     print("Number of containers in NS after clean : {}".format( len( list(salome_walk_on_containers(ns,[""])) )))
391     
392 def salome_shutdown_containers_without_session():
393     containersEntries = [elt for elt in naming_service.repr() if "/Containers/" == elt[:12]]
394     for containerEntry in containersEntries:
395         cont = naming_service.Resolve(containerEntry)
396         try:
397             cont.Shutdown()
398         except:
399             pass
400
401 def salome_shutdown_containers():
402     import KernelBasis
403     if KernelBasis.getSSLMode():
404         salome_shutdown_containers_without_session()
405     else:
406         salome_shutdown_containers_with_session()
407
408 class SessionContextManager:
409     def __enter__(self):
410         standalone()
411         salome_init()
412     def __exit__(self, type, value, traceback):
413         salome_close()
414
415 #to expose all objects to pydoc
416 __all__=dir()