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