Salome HOME
updated copyright message
[modules/kernel.git] / src / KERNEL_PY / kernel / services.py
1 # -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
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, or (at your option) any later version.
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 # Author: Guillaume Boulant (EDF/R&D)
22
23 ## \defgroup service service
24 #  \{ 
25 #  \details Helper for using %SALOME kernel services
26 #  \}
27
28 #
29 # WARNING: development notes
30 #
31 # This python module is aimed to be a (yet another?) end user
32 # interface to manipulate the KERNEL SALOME services. Note that it
33 # does not replace the salome module (i.e. what you get when typing
34 # "import salome", actually implemented in the file __init__.py of the
35 # salome python package). It provides instead functions that help to
36 # use the salome module in a end user context (development of domain
37 # specific tools by programmers that are not ten years experienced in
38 # SALOME development).
39
40 import salome
41 from .deprecation import is_called_by_sphinx
42 if not is_called_by_sphinx() and salome.lcc is None:
43     try:
44         salome.salome_init()
45     except Exception as e:
46         print(e)
47
48 # Note that the salome module provides you with standard SALOME
49 # objects: CORBA broker (orb): salome.orb lyfe cycle (lcc) :
50 # salome.lcc naming service : salome.naming_service 
51 # The default study : salome.myStudy
52 #
53 # Alternatively, you may obtain these objects directly with the
54 # following instructions:
55 #
56 #   from omniORB import CORBA
57 #   from LifeCycleCORBA import LifeCycleCORBA
58 #   orb = CORBA.ORB_init( [''], CORBA.ORB_ID )
59 #   lcc = LifeCycleCORBA( orb )
60
61 #   from SALOME_NamingServicePy import SALOME_NamingServicePy_i
62 #   naming_service = SALOME_NamingServicePy_i( orb )
63 #
64 # (See salome.py page in the KERNEL documentation)
65
66 #
67 # ==============================================================================
68 # Helper functions for SALOME components
69 # ==============================================================================
70 #
71
72 ## Get a %SALOME CORBA component from its name
73 #  \param componentName is the name of the component as declared in the XML
74 #  %SALOME catalog. %A loadable library with name lib<componentName>Engine.so
75 #  is supposed to be reachable. This library is supposed to provide a
76 #  factory function with the prototype:
77 #
78 #  \code
79 #  PortableServer::ObjectId * <componentName>Engine_factory( CORBA::ORB_ptr orb,
80 #                                                            PortableServer::POA_ptr poa,
81 #                                                            PortableServer::ObjectId* contId,
82 #                                                            const char *instanceName,
83 #                                                            const char *interfaceName );
84 #  \endcode
85 #
86 #  \param corbaModule is the name of the IDL module that contains the
87 #  definition of the interface of the component. This name corresponds
88 #  to the namespace of the servant classes.
89 #
90 #  \param containerType specified the container in which the servants are
91 #  executed.
92 #  \ingroup service
93 def getComponent(componentName = "SalomeTestComponent",
94                  corbaModule   = "Engines",
95                  containerType = "FactoryServer"):
96     """
97     Get a SALOME CORBA component from its name
98     """
99     import importlib
100     print("INF: getting component %s from CORBA module %s ..."%(componentName,corbaModule))
101     importlib.import_module(corbaModule)
102     component=salome.lcc.FindOrLoadComponent(containerType,componentName)
103     if component is None:
104         print("ERR: the SALOME component "+componentName+" can't be reached")
105     print("INF: component %s obtained from CORBA module %s"%(componentName,corbaModule))
106     return component
107
108 # Note that an alternative (and maybe better) method to get a component
109 # is to use the module catalog. Here, we just use the catalog to get
110 # the list of components defined in the current session.
111 import SALOME_ModuleCatalog
112
113 ## Get the list of names of all %SALOME componenents register in
114 #  the catalog.
115 #  \ingroup service
116 def getComponentList():
117     """
118     Get the list of names of all SALOME componenents register in
119     the catalog.
120     """
121     obj = salome.naming_service.Resolve('/Kernel/ModulCatalog')
122     catalog = obj._narrow(SALOME_ModuleCatalog.ModuleCatalog)
123     if not catalog:
124         raise RuntimeError("Can't access module catalog")
125     return catalog.GetComponentList()
126
127 import SALOMEDS
128 ## Get a study to create SALOME study. 
129 #  \warning you should use instead the variable salome.myStudy. 
130 #  This function is given for illustration of usage of the naming service
131 #  \ingroup service
132 def __getStudy_demo():
133     """
134     Get a study to create SALOME study. WARN: you
135     should use instead the variable salome.myStudy. This
136     function is given for illustration of usage of the naming service
137     """
138     naming_service = SALOME_NamingServicePy_i( orb )
139     obj = naming_service.Resolve( '/Study' )
140     study = obj._narrow( SALOMEDS.Study)
141     return study
142
143
144 #
145 # ==============================================================================
146 # Helper functions for manipulating objects, sobjects and entry
147 # ==============================================================================
148 #
149
150 # - the SObject is an item in a study (Study Object).
151 # - the entry is the identifier of an item.
152 # - the ID is the entry
153 # - the object (geom object or smesh object) is a CORBA servant
154 #   embedded in the SALOME component container and with a reference in
155 #   the SALOME study, so that it can be retrieved.
156
157 # __GBO__ WARN: theses functions are already defined in
158 # salome_study.py, but without the possibility to specify the
159 # underlying study (in salome_study.py, the study is the default study
160 # binded to the salome.myStudy attribute). TODO: see if it can be
161 # extends to the prototype (with the study as an argument) below and
162 # resorb the functions below.
163
164 def IDToObject(id, study=None):
165     myObj = None
166     if study is None:
167         myStudy = salome.myStudy
168     else:
169         myStudy = study
170     mySO = myStudy.FindObjectID(id);
171     if mySO is not None:
172         ok, anAttr = mySO.FindAttribute("AttributeIOR")
173         if ok:
174             AtIOR = anAttr._narrow(SALOMEDS.AttributeIOR)
175             if AtIOR.Value() != "":
176                 myObj = salome.orb.string_to_object(AtIOR.Value())
177     return myObj
178
179 def ObjectToSObject(obj, study=None):
180     mySO = None
181
182     if study is None:
183         myStudy = salome.myStudy
184     else:
185         myStudy = study
186
187     if obj is not None:
188         ior =  salome.orb.object_to_string(obj)
189         if ior != "":
190             mySO = myStudy.FindObjectIOR(ior)
191     return mySO
192
193 def ObjectToID(obj, study=None):
194     mySO = ObjectToSObject(obj,study)
195     if mySO:
196         return mySO.GetID()
197     return ""
198
199 def IDToSObject(id, study=None):
200     if study is None:
201         myStudy = salome.myStudy
202     else:
203         myStudy = study
204
205     mySO = myStudy.FindObjectID(id);
206     return mySO
207
208 def SObjectToID(sobject):
209     if sobject is None: return None
210     return sobject.GetID()
211
212
213 #
214 # ==============================================================================
215 # Basic use cases and unit tests
216 # ==============================================================================
217 #
218
219 def TEST_getComponent():
220     component=getComponent(componentName = "SalomeTestComponent")
221     
222     ref_string = 'TestComponent_i : L = 3'
223     res_string = component.Coucou(3)
224     if ref_string != ref_string:
225         return False
226     return True
227
228 def TEST_getComponentList():
229     componentList=getComponentList()
230     if 'SalomeTestComponent' not in componentList:
231         return False
232     return True
233
234 def TEST_createObject():
235     """
236     WARNING: for this test, we need GEOM (used to create an object) 
237     """
238     import GEOM
239     from salome.geom import geomBuilder
240     geompy = geomBuilder.New()
241
242     box = geompy.MakeBoxDXDYDZ(200, 200, 200)
243     id = geompy.addToStudy( box, 'box' )
244     return id
245
246 def TEST_objectsManipulation():
247     myEntry = TEST_createObject()
248
249     mySObject = IDToSObject(myEntry)
250     entry     = SObjectToID(mySObject)
251
252     if str(entry) != str(myEntry):
253         return False
254
255
256     myObject = IDToObject(myEntry)
257     print(myObject)
258     if myObject is None:
259         return False
260
261     return True
262
263 if __name__ == "__main__":
264     from . import unittester
265     unittester.run("services","TEST_getComponent")
266     unittester.run("services","TEST_getComponentList")
267     unittester.run("services","TEST_objectsManipulation")