]> SALOME platform Git repositories - modules/yacs.git/blob - src/runtime/RuntimeSALOME.cxx
Salome HOME
YACS in SSL mode
[modules/yacs.git] / src / runtime / RuntimeSALOME.cxx
1 // Copyright (C) 2006-2021  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //#define REFCNT
21 //
22 #ifdef REFCNT
23 #define private public
24 #define protected public
25 #include <omniORB4/CORBA.h>
26 #include <omniORB4/internal/typecode.h>
27 #include <omniORB4/internal/corbaOrb.h>
28 #endif
29
30 #include "yacsconfig.h"
31 #include "YACS_version.h"
32 #include "RuntimeSALOME.hxx"
33 #include "SALOMEDispatcher.hxx"
34 #include "Proc.hxx"
35 #include "TypeCode.hxx"
36 #include "WhileLoop.hxx"
37 #include "ForLoop.hxx"
38 #include "ForEachLoop.hxx"
39 #include "SalomeOptimizerLoop.hxx"
40 #include "Bloc.hxx"
41 #include "InputPort.hxx"
42 #include "OutputPort.hxx"
43 #include "PresetPorts.hxx"
44 #include "InputDataStreamPort.hxx"
45 #include "OutputDataStreamPort.hxx"
46 #include "Switch.hxx"
47 #include "SalomeProc.hxx"
48 #include "PyStdout.hxx"
49 //Catalog Loaders
50 #include "SessionCataLoader.hxx"
51
52 //Components
53 #include "CORBAComponent.hxx"
54 #include "SalomeComponent.hxx"
55 #include "SalomeHPComponent.hxx"
56 #include "SalomePythonComponent.hxx"
57 #include "CppComponent.hxx"
58
59 #include "SalomeContainer.hxx"
60 #include "CppContainer.hxx"
61 #include "SalomeHPContainer.hxx"
62
63 //Nodes
64 #include "PythonNode.hxx"
65 #include "CORBANode.hxx"
66 #include "XMLNode.hxx"
67 #include "CppNode.hxx"
68 #include "PresetNode.hxx"
69 #include "OutNode.hxx"
70 #include "StudyNodes.hxx"
71 #include "SalomePythonNode.hxx"
72 #include "DistributedPythonNode.hxx"
73
74 //CORBA proxy ports
75 #include "CORBACORBAConv.hxx"
76 #include "CORBAPythonConv.hxx"
77 #include "CORBAXMLConv.hxx"
78 #include "CORBACppConv.hxx"
79 #include "CORBANeutralConv.hxx"
80
81 #include "TypeConversions.hxx"
82 //Python proxy ports
83 #include "PythonCORBAConv.hxx"
84 #include "PythonXMLConv.hxx"
85 #include "PythonCppConv.hxx"
86 #include "PythonNeutralConv.hxx"
87 #include "PythonInitConv.hxx"
88
89 //Neutral proxy ports
90 #include "NeutralCORBAConv.hxx"
91 #include "NeutralPythonConv.hxx"
92 #include "NeutralXMLConv.hxx"
93 #include "NeutralCppConv.hxx"
94 #include "NeutralInitConv.hxx"
95
96 //C++ proxy ports
97 #include "CppCORBAConv.hxx"
98 #include "CppPythonConv.hxx"
99 #include "CppXMLConv.hxx"
100 #include "CppCppConv.hxx"
101 #include "CppNeutralConv.hxx"
102
103 //XML proxy ports
104 #include "XMLCORBAConv.hxx"
105 #include "XMLPythonConv.hxx"
106 #include "XMLCppConv.hxx"
107 #include "XMLNeutralConv.hxx"
108
109 //Calcium specific ports
110 #include "CalStreamPort.hxx"
111
112 #ifdef SALOME_KERNEL
113 #include "SALOME_NamingService_Wrapper.hxx"
114 #include "SALOME_LifeCycleCORBA.hxx"
115 #include "SALOME_ResourcesManager.hxx"
116 #include "SALOME_ContainerManager.hxx"
117 #include "SALOMEconfig.h"
118 #include CORBA_CLIENT_HEADER(SALOME_ContainerManager)
119
120 #endif
121   
122 #include <libxml/parser.h>
123 #include <omniORB4/CORBA.h>
124 #include <iostream>
125 #include <sstream>
126 #include <cassert>
127
128 //#define _DEVDEBUG_
129 #include "YacsTrace.hxx"
130
131 using namespace std;
132 using namespace YACS::ENGINE;
133
134 std::unique_ptr<SALOME_NamingService_Container_Abstract> RuntimeSALOME::getNS()
135 {
136   std::unique_ptr<SALOME_NamingService_Container_Abstract> ret(new SALOME_NamingService_Wrapper);
137   return ret;
138 }
139
140 void RuntimeSALOME::setRuntime(long flags, int argc, char* argv[]) // singleton creation (not thread safe!)
141 {
142   if (! Runtime::_singleton)
143     {
144       RuntimeSALOME* r=new RuntimeSALOME(flags, argc, argv);
145       Runtime::_singleton = r;
146       r->initBuiltins();
147     }
148   DEBTRACE("RuntimeSALOME::setRuntime() done !");
149 }
150
151 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
152 {
153   YASSERT(RuntimeSALOME::getSingleton());
154   return dynamic_cast< RuntimeSALOME* >(RuntimeSALOME::getSingleton());
155 }
156
157 /**
158  *  Singleton creation, initialize converter map
159  */
160   
161 RuntimeSALOME::RuntimeSALOME()
162 {
163   YASSERT(0);
164 }
165
166 void RuntimeSALOME::initBuiltins()
167 {
168   //Fill the builtin catalog with nodes specific to the runtime
169   std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
170   std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
171   std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
172   std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
173   nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
174   nodeMap["PyScript"]=new PythonNode("PyScript");
175   nodeMap["CORBANode"]=new CORBANode("CORBANode");
176   nodeMap["XmlNode"]=new XmlNode("XmlNode");
177   nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
178   nodeMap["CppNode"]=new CppNode("CppNode");
179   nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
180   nodeMap["PresetNode"]=new PresetNode("PresetNode");
181   nodeMap["OutNode"]=new OutNode("OutNode");
182   nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
183   nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
184   composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
185   typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
186   typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
187   typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
188   typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
189   typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
190   typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
191   typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
192   typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
193   std::list<TypeCodeObjref *> ltc;
194   typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
195   typeMap["seqpyobj"]= createSequenceTc("seqpyobj","seqpyobj",typeMap["pyobj"]);
196   composednodeMap["Bloc"]=createBloc("Bloc");
197   composednodeMap["Switch"]=createSwitch("Switch");
198   composednodeMap["WhileLoop"]=createWhileLoop("WhileLoop");
199   composednodeMap["ForLoop"]=createForLoop("ForLoop");
200   composednodeMap["ForEachLoop_double"]=createForEachLoop("ForEachLoop_double",Runtime::_tc_double);
201   composednodeMap["ForEachLoop_string"]=createForEachLoop("ForEachLoop_string",Runtime::_tc_string);
202   composednodeMap["ForEachLoop_int"]=createForEachLoop("ForEachLoop_int",Runtime::_tc_int);
203   composednodeMap["ForEachLoop_bool"]=createForEachLoop("ForEachLoop_bool",Runtime::_tc_bool);
204   composednodeMap["ForEachLoop_pyobj"]=createForEachLoop("ForEachLoop_pyobj",typeMap["pyobj"]);;
205   ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
206   t->addMember("ref",_tc_string);
207   typeMap["dataref"]= t;
208 }
209
210 RuntimeSALOME::RuntimeSALOME(long flags, int argc, char* argv[])
211 {
212   // If all flags (apart the IsPyExt flags) are unset, force them to true
213   if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
214     flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
215           +  RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
216
217   // Salome Nodes implies Corba Nodes
218   if (flags & RuntimeSALOME::UseSalome)
219     flags |= RuntimeSALOME::UseCorba;
220
221   // Corba Nodes implies Python Nodes
222   if (flags & RuntimeSALOME::UseCorba)
223     flags |= RuntimeSALOME::UsePython;
224
225   _useCorba = flags & RuntimeSALOME::UseCorba;
226   _usePython = flags & RuntimeSALOME::UsePython;
227   _useCpp = flags & RuntimeSALOME::UseCpp;
228   _useXml = flags & RuntimeSALOME::UseXml;
229
230   /* Init libxml */
231   xmlInitParser();
232
233   if (_useCpp)    _setOfImplementation.insert(CppNode::IMPL_NAME);
234   if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
235   if (_useCorba)  _setOfImplementation.insert(CORBANode::IMPL_NAME);
236   if (_useXml)    _setOfImplementation.insert(XmlNode::IMPL_NAME);
237   init(flags, argc, argv);
238 }
239
240 RuntimeSALOME::~RuntimeSALOME()
241 {
242   DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
243   // destroy catalog loader prototypes
244   std::map<std::string, CatalogLoader*>::const_iterator pt;
245   for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
246     {
247       delete (*pt).second;
248     }
249 }
250
251 //! CORBA and Python initialization
252 /*!
253  *  \param flags contains several bits
254  *            bit0 (ispyext) true when method is called from Python
255  *                           (Python initialization must not be done!)
256  *            bit1 (UsePython) true if python nodes are needed
257  *            bit1 (UseCorba)  true if CORBA nodes are needed
258  *            bit1 (UseXml)    true if python nodes are needed
259  *            bit1 (UseCpp)    true if C++ nodes are needed
260  *            bit1 (UseSalome) true if Salome nodes are needed
261  *  \param argc number of command line arguments (used to initialize the Python interpreter)
262  *  \param argv command line arguments (used to initialize the Python interpreter)
263  *
264  */
265
266 void RuntimeSALOME::init(long flags, int argc, char* argv[])
267 {
268   bool ispyext = flags & RuntimeSALOME::IsPyExt;
269   if (_useCorba)
270     {
271       PortableServer::POA_var root_poa;
272       PortableServer::POAManager_var pman;
273       CORBA::Object_var obj;
274       int nbargs = 0; char **args = 0;
275       _orb = CORBA::ORB_init (nbargs, args);
276       obj = _orb->resolve_initial_references("RootPOA");
277       root_poa = PortableServer::POA::_narrow(obj);
278       pman = root_poa->the_POAManager();
279       pman->activate();
280
281 #ifdef REFCNT
282       DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
283 #endif
284       obj = _orb->resolve_initial_references("DynAnyFactory");
285       _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
286     }
287
288   if (_usePython)
289     {
290       DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
291
292       // Initialize Python interpreter in embedded mode
293       if (!Py_IsInitialized())
294         {
295 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
296           Py_Initialize(); 
297 #else
298           Py_InitializeEx(0); // do not install signal handlers
299 #endif
300           if (argc > 0 && argv != NULL)
301             {
302               wchar_t **changed_argv = new wchar_t*[argc];
303               for (int i = 0; i < argc; i++)
304               {
305                 changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
306               }
307               PySys_SetArgv(argc, changed_argv);
308             } 
309           else
310             {
311               int pyArgc = 1;
312               char* pyArgv[1];
313               char defaultName[] = "SALOME_YACS_RUNTIME";
314               wchar_t **changed_pyArgv = new wchar_t*[pyArgc];
315               pyArgv[0] = defaultName;
316               for (int i = 0; i < pyArgc; i++)
317               {
318                 changed_pyArgv[i] = Py_DecodeLocale(pyArgv[i], NULL);
319               }
320               PySys_SetArgv(pyArgc, changed_pyArgv);
321             }
322 #if PY_VERSION_HEX < 0x03070000
323           PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
324 #endif
325           PyEval_SaveThread(); /* Release the thread state */
326           //here we do not have the Global Interpreter Lock
327         }
328
329       PyObject *mainmod,*pyapi,*res ;
330       PyObject *globals;
331       PyGILState_STATE gstate;
332       gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
333     
334       mainmod = PyImport_AddModule("__main__");
335       globals = PyModule_GetDict(mainmod);
336       /* globals is a borrowed reference */
337   
338       if (PyDict_GetItemString(globals, "__builtins__") == NULL) 
339         {
340           PyObject *bimod = PyImport_ImportModule("builtins");
341           if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
342             Py_FatalError("can't add __builtins__ to __main__");
343           Py_DECREF(bimod);
344         }
345
346       _bltins = PyEval_GetBuiltins();  /* borrowed ref */
347
348       if (_useCorba)
349         {
350
351           //init section
352           _omnipy = PyImport_ImportModule((char*)"_omnipy");
353           if (!_omnipy)
354             {
355               PyErr_Print();
356               PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
357               goto out;
358             }
359           pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
360           if (!pyapi)
361             {
362               goto out;
363             }
364           _api = (omniORBpyAPI*)PyCapsule_GetPointer(pyapi,"_omnipy.API");
365           Py_DECREF(pyapi);
366
367           res=PyRun_String("\n"
368                            "from math import *\n"
369                            "import sys\n"
370                            "sys.path.insert(0,'.')\n"
371                            "from omniORB import CORBA\n"
372                            "from omniORB import any\n"
373                            "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
374                            "#print(sys.getrefcount(orb))\n"
375                            "try:\n"
376                            "  import SALOME\n"
377                            "except:\n"
378                            "  pass\n"
379                            "\n",
380                            Py_file_input,globals,globals );
381           if(res == NULL)
382             {
383               PyErr_Print();
384               goto out;
385             }
386           Py_DECREF(res);
387
388           _pyorb = PyDict_GetItemString(globals,"orb");
389           /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
390
391           PyObject *pyany;
392           pyany = PyDict_GetItemString(globals,"any");
393           /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
394
395 #ifdef REFCNT
396           DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
397 #endif
398         }
399       out:
400         PyGILState_Release(gstate); // Release the Global Interpreter Lock
401     }
402   if (_useCorba)
403     {
404       // initialize the catalogLoaderFactory map with the session one
405       _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
406     }
407 }
408
409 void RuntimeSALOME::fini()
410 {
411   if (_usePython)
412     {
413       PyGILState_STATE gstate = PyGILState_Ensure();
414 #ifdef REFCNT
415       DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
416 #endif
417       PyObject *mainmod, *globals;
418       mainmod = PyImport_AddModule("__main__");
419       globals = PyModule_GetDict(mainmod);
420       if (_useCorba)
421         {
422           PyObject* res;
423           res=PyRun_String("orb.destroy()\n"
424                            "\n",
425                            Py_file_input,globals,globals );
426           if(res == NULL)
427             PyErr_Print();
428           else
429             Py_DECREF(res);
430         }
431       std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
432       delete nodeMap["PyFunction"];
433       delete nodeMap["PyScript"];
434       delete nodeMap["SalomePythonNode"];
435       nodeMap.erase("PyFunction");
436       nodeMap.erase("PyScript");
437       nodeMap.erase("SalomePythonNode");
438
439       Py_Finalize();
440 #ifdef REFCNT
441       DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
442 #endif
443     }
444   else
445     {
446       if (_useCorba)
447         {
448 #ifdef REFCNT
449           DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
450 #endif
451           _orb->destroy();
452         }
453     }
454 }
455
456 std::vector< std::pair<std::string,int> > RuntimeSALOME::getCatalogOfComputeNodes() const
457 {
458   CORBA::ORB_ptr orb(getOrb());
459   SALOME_NamingService_Wrapper namingService;
460   try
461   {
462     namingService.init_orb(orb);
463   }
464   catch(SALOME_Exception& e)
465   {
466     throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Unable to contact the SALOME Naming Service");
467   }
468   CORBA::Object_var obj(namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS));
469   if(CORBA::is_nil(obj))
470     throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Unable to access to the resource manager !");
471   Engines::ResourcesManager_var resManager(Engines::ResourcesManager::_narrow(obj));
472   if(CORBA::is_nil(resManager))
473     throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Internal error ! The entry attached to the res manager in NS does not have right type !");
474   std::vector< std::pair<std::string,int> > ret;
475   Engines::ResourceParameters params;
476   params.name = "";
477   params.hostname = "";
478   params.OS = "";
479   params.nb_proc = 0;
480   params.mem_mb = 0;
481   params.cpu_clock = 0;
482   params.nb_node = 0;
483   params.nb_proc_per_node = 0;
484   params.policy = "";
485   params.can_launch_batch_jobs = false;
486   params.can_run_containers = true;
487   params.componentList.length(0);
488   try
489   {
490     Engines::ResourceList_var resourceList;
491     resourceList = resManager->GetFittingResources(params);
492     ret.reserve(resourceList->length());
493     for(int i = 0; i<resourceList->length(); i++)
494     {
495       const char* resource_name = resourceList[i];
496       std::string std_resource_name = resource_name;
497       Engines::ResourceDefinition_var resource_definition
498                               = resManager->GetResourceDefinition(resource_name);
499       int nb_cores = resource_definition->nb_node *
500                      resource_definition->nb_proc_per_node;
501       ret.push_back(std::pair<std::string,int>(resource_name, nb_cores));
502     }
503   }
504   catch(SALOME::SALOME_Exception& e)
505   {
506     std::string message;
507     message=e.details.text.in();
508     throw Exception(message);
509   }
510
511   return ret;
512 }
513
514 std::string RuntimeSALOME::getVersion() const
515 {
516 #ifdef YACS_DEVELOPMENT
517   return CORBA::string_dup(YACS_VERSION_STR"dev");
518 #else
519   return CORBA::string_dup(YACS_VERSION_STR);
520 #endif
521 }
522
523 Proc* RuntimeSALOME::createProc(const std::string& name)
524 {
525   return new SalomeProc(name);
526 }
527
528 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
529                                             std::list<TypeCodeObjref *> ltc)
530 {
531   std::string myName;
532   if(id == "") myName = "IDL:" + name + ":1.0";
533   else myName = id;
534   return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
535 }
536
537 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
538                                            const std::string& name,
539                                            TypeCode *content)
540 {
541   return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
542 };
543
544 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
545 {
546   std::string myName;
547   if(id == "") myName = "IDL:" + name + ":1.0";
548   else myName = id;
549   return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
550 }
551
552 Bloc* RuntimeSALOME::createBloc(const std::string& name)
553 {
554   return new Bloc(name);
555 }
556
557 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
558 {
559   return new WhileLoop(name);
560 }
561
562 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
563 {
564   return new ForLoop(name);
565 }
566
567 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
568                                                   bool algInitOnFile, const std::string& kind, Proc * procForTypes)
569 {
570   OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
571                                           new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
572   ol->edGetNbOfBranchesPort()->edInit(1);
573   return ol;
574 }
575
576 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
577 {
578   DataNode* node;
579   if(kind == "" )
580     {
581       node = new PresetNode(name);
582       return node;
583     }
584   else if(kind == "study" )
585     {
586       return new StudyInNode(name);
587     }
588   std::string msg="DataNode kind ("+kind+") unknown";
589   throw Exception(msg);
590 }
591
592 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
593 {
594   if(kind == "" )
595     {
596       return new OutNode(name);
597     }
598   else if(kind == "study" )
599     {
600       return new StudyOutNode(name);
601     }
602
603   std::string msg="OutDataNode kind ("+kind+") unknown";
604   throw Exception(msg);
605 }
606
607 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
608 {
609   InlineFuncNode* node;
610   if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
611     {
612       node = new PyFuncNode(name);
613       return node;
614     }
615   if(kind == DistributedPythonNode::KIND)
616     return new DistributedPythonNode(name);
617   std::string msg="FuncNode kind ("+kind+") unknown";
618   throw Exception(msg);
619 }
620
621 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
622 {
623   InlineNode* node;
624   if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
625     {
626       node = new PythonNode(name);
627       return node;
628     }
629   std::string msg="ScriptNode kind ("+kind+") unknown";
630   throw Exception(msg);
631 }
632
633 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
634 {
635   ServiceNode* node;
636   if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
637     {
638       node = new CORBANode(name);
639       return node;
640     }
641   else if(kind == XmlNode::KIND)
642     {
643       node = new XmlNode(name);
644       return node;
645     }
646   std::string msg="RefNode kind ("+kind+") unknown";
647   throw Exception(msg);
648 }
649
650 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
651 {
652   ServiceNode* node;
653   if(kind == "" || kind == SalomeNode::KIND )
654     {
655       node=new SalomeNode(name);
656       return node;
657     }
658   else if (kind == CppNode::KIND) 
659     {
660       node = new CppNode(name);
661       return node;
662     }
663   std::string msg="CompoNode kind ("+kind+") unknown";
664   throw Exception(msg);
665 }
666
667 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
668 {
669   if(kind == "" || kind == SalomeNode::KIND )
670     return new SalomePythonNode(name);
671   std::string msg="CompoNode kind ("+kind+") unknown";
672   throw Exception(msg);
673 }
674
675 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
676                                                           const std::string& kind)
677 {
678   ComponentInstance* compo;
679   if(kind == "" || kind == SalomeComponent::KIND) 
680     return new SalomeComponent(name);
681   else if(kind == CORBAComponent::KIND)
682     return new CORBAComponent(name);
683   else if(kind == SalomePythonComponent::KIND)
684     return new SalomePythonComponent(name);
685   else if (kind == CppComponent::KIND)
686     return new CppComponent(name);
687   else if (kind == SalomeHPComponent::KIND)
688     return new SalomeHPComponent(name);
689   std::string msg="Component Instance kind ("+kind+") unknown";
690   throw Exception(msg);
691 }
692
693 Container *RuntimeSALOME::createContainer(const std::string& kind)
694 {
695   if(kind == "" || kind == SalomeContainer::KIND)
696     return new SalomeContainer;
697   if(kind==SalomeHPContainer::KIND)
698     return new SalomeHPContainer;
699   else if (kind == CppContainer::KIND)
700     return new CppContainer;
701   std::string msg="Container kind ("+kind+") unknown";
702   throw Exception(msg);
703 }
704
705 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
706                                            const std::string& impl,
707                                            Node * node,
708                                            TypeCode * type)
709 {
710   if(impl == CppNode::IMPL_NAME)
711     {
712       return new InputCppPort(name, node, type);
713     }
714   else if(impl == PythonNode::IMPL_NAME)
715     {
716       return new InputPyPort(name, node, type);
717     }
718   else if(impl == CORBANode::IMPL_NAME)
719     {
720       return new InputCorbaPort(name, node, type);
721     }
722   else if(impl == XmlNode::IMPL_NAME)
723     {
724       return new InputXmlPort(name, node, type);
725     }
726   else
727     {
728       stringstream msg;
729       msg << "Cannot create " << impl << " InputPort" ;
730       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
731       throw Exception(msg.str());
732     }
733 }
734
735 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
736                                              const std::string& impl,
737                                              Node * node,
738                                              TypeCode * type)
739 {
740   if(impl == CppNode::IMPL_NAME)
741     {
742       return new OutputCppPort(name, node, type);
743     }
744   else if(impl == PythonNode::IMPL_NAME)
745     {
746       return new OutputPyPort(name, node, type);
747     }
748   else if(impl == CORBANode::IMPL_NAME)
749     {
750       return new OutputCorbaPort(name, node, type);
751     }
752   else if(impl == XmlNode::IMPL_NAME)
753     {
754       return new OutputXmlPort(name, node, type);
755     }
756   else
757     {
758       stringstream msg;
759       msg << "Cannot create " << impl << " OutputPort" ;
760       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
761       throw Exception(msg.str());
762     }
763 }
764
765 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
766                                                               Node *node,TypeCode *type)
767 {
768   DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
769   if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
770     {
771       return new InputCalStreamPort(name,node,type);
772     }
773   else
774     {
775       return new InputDataStreamPort(name,node,type);
776     }
777 }
778
779 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
780                                                                 Node *node,TypeCode *type)
781 {
782   DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
783   if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
784     {
785       return new OutputCalStreamPort(name,node,type);
786     }
787   else
788     {
789       return new OutputDataStreamPort(name,node,type);
790     }
791 }
792
793 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation 
794 /*!
795  *  \param source : InputPort to be adapted
796  *  \param impl : new implementation (C++, python, CORBA, XML, Neutral)
797  *  \param type : data type provided by the InputPort
798  *  \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
799  * 
800  * \return : adapted InputPort
801  */
802 InputPort* RuntimeSALOME::adapt(InputPort* source,
803                                 const std::string& impl,
804                                 TypeCode * type,bool init)
805 {
806   string imp_source=source->getNode()->getImplementation();
807   if(imp_source == PythonNode::IMPL_NAME)
808     {
809       return adapt((InputPyPort*)source,impl,type,init);
810     }
811   else if(imp_source == CppNode::IMPL_NAME)
812     {
813       return adapt((InputCppPort*)source,impl,type,init);
814     }
815   else if(imp_source == CORBANode::IMPL_NAME)
816     {
817       return adapt((InputCorbaPort*)source,impl,type,init);
818     }
819   else if(imp_source == XmlNode::IMPL_NAME)
820     {
821       return adapt((InputXmlPort*)source,impl,type,init);
822     }
823   else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
824     {
825       return adaptNeutral(source,impl,type,init);
826     }
827   else
828     {
829       stringstream msg;
830       msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
831       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
832       throw ConversionException(msg.str());
833     }
834 }
835
836 //! Adapter function for InPropertyPort
837 /*!
838  *  \param source : InPropertyPort to be adapted
839  *  \param impl : new implementation (C++, python, CORBA, XML, Neutral)
840  *  \param type : data type provided by the InPropertyPort
841  *  \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
842  * 
843  * \return : adapted InputPort
844  */
845 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
846                                 const std::string& impl,
847                                 TypeCode * type,bool init)
848 {
849   return adaptNeutral((InputPort *)source,impl,type,init);
850 }
851
852 //! Adapt a Neutral input port to a Corba output port
853 /*!
854  *   \param inport : Neutral input port to adapt to Corba type type
855  *   \param type : output port type
856  *   \return an adaptated input port of type InputCorbaPort
857  */
858 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
859                       TypeCode * type)
860 {
861   // BEWARE : using the generic check
862   if(inport->edGetType()->isAdaptable(type))
863     {
864       //the output data is convertible to inport type
865       return new CorbaNeutral(inport);
866     }
867   //non convertible type
868   stringstream msg;
869   msg << "Cannot connect Corba output port with type: " << type->id() ;
870   msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
871 #ifdef _DEVDEBUG_
872   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
873 #endif
874   throw ConversionException(msg.str());
875 }
876
877 //! Adapt a Neutral input port to a Python output port
878 /*!
879  *   \param inport : input port to adapt to Python type type
880  *   \param type : output port type
881  *   \return an adaptated input port of type InputPyPort
882  */
883 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
884                       TypeCode * type)
885 {
886   // BEWARE : using the generic check
887   if(inport->edGetType()->isAdaptable(type))
888     {
889       //convertible type
890       return new PyNeutral(inport);
891     }
892   //last chance : an py output that is seq[objref] can be connected to a neutral input objref (P13268)
893   else if(type->kind()==Sequence && type->contentType()->kind()==Objref && inport->edGetType()->kind()==Objref)
894     {
895       return new PyNeutral(inport);
896     }
897   //non convertible type
898   stringstream msg;
899   msg << "Cannot connect Python output port with type: " << type->id() ;
900   msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
901 #ifdef _DEVDEBUG_
902   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
903 #endif
904   throw ConversionException(msg.str());
905 }
906
907 //! Adapt a Neutral input port to a Xml output port 
908 /*!
909  *   \param inport : input port to adapt to Xml type type
910  *   \param type : output port type
911  *   \return an input port of type InputXmlPort
912  */
913 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
914                       TypeCode * type)
915 {
916   // BEWARE : using the generic check
917   if(inport->edGetType()->isAdaptable(type))
918     {
919       //convertible type
920       return new XmlNeutral(inport);
921     }
922   //non convertible type
923   stringstream msg;
924   msg << "Cannot connect Xml output port with type: " << type->id() ;
925   msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
926 #ifdef _DEVDEBUG_
927   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
928 #endif
929   throw ConversionException(msg.str());
930 }
931
932 //! Adapt a Neutral input port to a C++ output port 
933 /*!
934  *   \param inport : input port to adapt to C++ type type
935  *   \param type : output port type
936  *   \return an input port of type InputCppPort
937  */
938 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
939                       TypeCode * type)
940 {
941   DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
942   if(isAdaptableNeutralCpp(type,inport->edGetType()))
943     {
944       //convertible type
945       return new CppNeutral(inport);
946     }
947   //non convertible type
948   stringstream msg;
949   msg << "Cannot connect Cpp output port with type: " << type->id() ;
950   msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
951 #ifdef _DEVDEBUG_
952   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
953 #endif
954   throw ConversionException(msg.str());
955 }
956
957 //! Adapt a Neutral input port to connect it to an output port with a given implementation
958 /*!
959  *   \param source : Neutral input port to adapt to implementation impl and type type
960  *   \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
961  *   \param type : output port supported type
962  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
963  *   \return       the adaptated port
964  */
965 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
966                                        const std::string& impl,
967                                        TypeCode * type,bool init)
968 {
969   if(impl == CppNode::IMPL_NAME)
970     {
971       return adaptNeutralToCpp(source,type);
972     }
973   else if(impl == PythonNode::IMPL_NAME)
974     {
975       return adaptNeutralToPython(source,type);
976     }
977   else if(impl == CORBANode::IMPL_NAME)
978     {
979       return adaptNeutralToCorba(source,type);
980     }
981   else if(impl == XmlNode::IMPL_NAME )
982     {
983       return adaptNeutralToXml(source,type);
984     }
985   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
986     {
987       if(init)
988         return new NeutralInit(source);
989       else
990         return new ProxyPort(source);
991     }
992   stringstream msg;
993   msg << "Cannot connect InputPort : unknown implementation " << impl;
994   msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
995   throw ConversionException(msg.str());
996 }
997
998 //! Adapt a XML input port to connect it to a CORBA output port 
999 /*!
1000  *   \param inport : input port to adapt to CORBA type type
1001  *   \param type : type supported by output port
1002  *   \return an adaptator port of type InputCorbaPort 
1003  */
1004
1005 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
1006                                           TypeCode * type)
1007 {
1008   if(isAdaptableXmlCorba(type,inport->edGetType()))
1009     {
1010       //output type is convertible to input type
1011       return new CorbaXml(inport);
1012     }
1013   //output type is not convertible
1014   stringstream msg;
1015   msg << "Cannot connect Corba output port with type: " << type->id() ;
1016   msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1017 #ifdef _DEVDEBUG_
1018   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1019 #endif
1020   throw ConversionException(msg.str());
1021 }
1022
1023 //! Adapt a XML input port to a Python output port
1024 /*!
1025  *   \param inport : input port to adapt to Python type type
1026  *   \param type : output port type
1027  *   \return an adaptated input port of type InputPyPort
1028  */
1029 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
1030                       TypeCode * type)
1031 {
1032   if(inport->edGetType()->isAdaptable(type))
1033     {
1034       //the output data is convertible to inport type
1035       return new PyXml(inport);
1036     }
1037   //non convertible type
1038   stringstream msg;
1039   msg << "Cannot connect Python output port with type: " << type->id() ;
1040   msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1041 #ifdef _DEVDEBUG_
1042   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1043 #endif
1044   throw ConversionException(msg.str());
1045 }
1046
1047 //! Adapt a XML input port to a C++ output port
1048 /*!
1049  *   \param inport : input port to adapt to C++ type type
1050  *   \param type : output port type
1051  *   \return an adaptated input port of type InputPyPort
1052  */
1053 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
1054                       TypeCode * type)
1055 {
1056   DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
1057   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
1058   if(type->isAdaptable(inport->edGetType()))
1059     {
1060       //the output data is convertible to inport type
1061       return new CppXml(inport);
1062     }
1063   //non convertible type
1064   stringstream msg;
1065   msg << "Cannot connect Cpp output port with type: " << type->id() ;
1066   msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1067 #ifdef _DEVDEBUG_
1068   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1069 #endif
1070   throw ConversionException(msg.str());
1071 }
1072
1073 //! Adapt a XML input port to a Neutral output port
1074 /*!
1075  *   \param inport : input port to adapt to Neutral type type
1076  *   \param type : output port type
1077  *   \return an adaptated input port of type Neutralxxxx
1078  */
1079 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
1080                       TypeCode * type)
1081 {
1082   if(inport->edGetType()->isAdaptable(type))
1083     {
1084       //the output data is convertible to inport type
1085       return new NeutralXml(inport);
1086     }
1087   //non convertible type
1088   stringstream msg;
1089   msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
1090   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1091   throw ConversionException(msg.str());
1092 }
1093
1094 //! Adapt a XML input port to a Xml output port
1095 /*!
1096  *   \param inport : input port to adapt to Xml type type
1097  *   \param type : output port type
1098  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1099  *   \return an adaptated input port of type Xmlxxxx
1100  */
1101 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
1102                       TypeCode * type,bool init)
1103 {
1104   if(init)
1105     return new ProxyPort(inport);
1106
1107   if(inport->edGetType()->isAdaptable(type))
1108     return new ProxyPort(inport);
1109
1110   stringstream msg;
1111   msg << "Cannot connect Xml output port with type: " << type->id() ;
1112   msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1113 #ifdef _DEVDEBUG_
1114   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1115 #endif
1116   throw ConversionException(msg.str());
1117 }
1118
1119 //! Adapt an Xml input port to an output port which implementation is given by impl
1120 /*!
1121  *   \param source : input port to adapt to implementation impl and type type
1122  *   \param impl : output port implementation (C++, Python or Corba)
1123  *   \param type : output port supported type
1124  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1125  *   \return       the adaptated port
1126  */
1127
1128 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1129                                 const std::string& impl,
1130                                 TypeCode * type,bool init)
1131 {
1132   if(impl == CORBANode::IMPL_NAME)
1133     {
1134       return adaptXmlToCorba(source,type);
1135     }
1136   else if(impl == PythonNode::IMPL_NAME)
1137     {
1138       return adaptXmlToPython(source,type);
1139     }
1140   else if(impl == CppNode::IMPL_NAME)
1141     {
1142       return adaptXmlToCpp(source,type);
1143     }
1144   else if(impl == XmlNode::IMPL_NAME )
1145     {
1146       return adaptXmlToXml(source,type,init);
1147     }
1148   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1149     {
1150       return adaptXmlToNeutral(source,type);
1151     }
1152   else
1153     {
1154       stringstream msg;
1155       msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1156       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1157       throw ConversionException(msg.str());
1158     }
1159 }
1160
1161
1162 //! Adapt a CORBA input port to a CORBA output port 
1163 /*!
1164  *   \param inport : input port to adapt to CORBA outport data type
1165  *   \param type : outport data type 
1166  *   \return an adaptator port of type InputCORBAPort 
1167  */
1168 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1169                                             TypeCode * type)
1170 {
1171   if(type->isA(inport->edGetType()))
1172     {
1173       //types are compatible : no conversion 
1174       //outport data type is more specific than inport required type
1175       //so the inport can be used safely 
1176       return new ProxyPort(inport);
1177     }
1178   else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1179     {
1180       //ouport data can be converted to inport data type
1181       return new CorbaCorba(inport);
1182     }
1183   //outport data can not be converted
1184   stringstream msg;
1185   msg << "Cannot connect Corba output port with type: " << type->id() ;
1186   msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1187 #ifdef _DEVDEBUG_
1188   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1189 #endif
1190   throw ConversionException(msg.str());
1191 }
1192
1193 //! Adapt a CORBA input port to a Python output port 
1194 /*!
1195  *   \param inport : input port to adapt to Python type type
1196  *   \param type : outport data type 
1197  *   \return an adaptator port of type InputPyPort 
1198  */
1199
1200 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1201                                              TypeCode * type)
1202 {
1203   if(inport->edGetType()->kind() == Double)
1204     {
1205       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1206     }
1207   else if(inport->edGetType()->kind() == Int)
1208     {
1209       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1210     }
1211   else if(inport->edGetType()->kind() == String)
1212     {
1213       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1214     }
1215   else if(inport->edGetType()->kind() == Bool)
1216     {
1217       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1218     }
1219   else if(inport->edGetType()->kind() == Objref )
1220     {
1221       if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1222         {
1223           return new PyCorbaObjref(inport);
1224         }
1225       else
1226         {
1227           stringstream msg;
1228           msg << "Cannot connect Python output port with type: " << type->id() ;
1229           msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1230           msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1231           throw ConversionException(msg.str());
1232         }
1233     }
1234   else if(inport->edGetType()->kind() == Sequence)
1235     {
1236       if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1237         {
1238           return new PyCorbaSequence(inport);
1239         }
1240       else
1241         {
1242           stringstream msg;
1243           msg << "Cannot convert this sequence type " ;
1244           msg << __FILE__ << ":" <<__LINE__;
1245           throw ConversionException(msg.str());
1246         }
1247     }
1248   else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1249     {
1250       if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1251         {
1252           return new PyCorbaStruct(inport);
1253         }
1254       else
1255         {
1256           stringstream msg;
1257           msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1258           msg << __FILE__ << ":" <<__LINE__;
1259           throw ConversionException(msg.str());
1260         }
1261     }
1262   // Adaptation not possible
1263   stringstream msg;
1264   msg << "Cannot connect Python output port with type: " << type->id() ;
1265   msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1266 #ifdef _DEVDEBUG_
1267   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1268 #endif
1269   throw ConversionException(msg.str());
1270 }
1271
1272 //! Adapt a CORBA input port to connect it to a XML output port 
1273 /*!
1274  *   \param inport : input port to adapt to Xml type type
1275  *   \param type : type supported by output port
1276  *   \return an adaptator port of type InputXmlPort 
1277  */
1278
1279 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1280                                           TypeCode * type)
1281 {
1282   // BEWARE : using the generic check
1283   if(inport->edGetType()->isAdaptable(type))
1284     {
1285       //output type is convertible to input type
1286       return new XmlCorba(inport);
1287     }
1288   //output type is not convertible
1289   stringstream msg;
1290   msg << "Cannot connect Xml output port with type: " << type->id() ;
1291   msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1292 #ifdef _DEVDEBUG_
1293   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1294 #endif
1295   throw ConversionException(msg.str());
1296 }
1297
1298 //! Adapt a CORBA input port to a C++ output port 
1299 /*!
1300  *   \param inport : input port to adapt to C++ type type
1301  *   \param type : outport data type 
1302  *   \return an adaptator port of type InputCPPPort 
1303  */
1304
1305 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1306                                           TypeCode * type)
1307 {
1308   DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1309   if(isAdaptableCorbaCpp(type,inport->edGetType()))
1310     {
1311       //output type is convertible to input type
1312       return new CppCorba(inport);
1313     }
1314   //output type is not convertible
1315   stringstream msg;
1316   msg << "Cannot connect Cpp output port with type: " << type->id() ;
1317   msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1318 #ifdef _DEVDEBUG_
1319   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1320 #endif
1321   throw ConversionException(msg.str());
1322 }
1323
1324 //! Adapt a CORBA input port to a neutral data 
1325 /*!
1326  *   \param inport : InputPort to adapt to Neutral type type
1327  *   \param type : outport data type 
1328  *   \return an adaptator port of type Neutralxxxx
1329  */
1330
1331 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1332                                               TypeCode * type)
1333 {
1334   if(inport->edGetType()->kind() == Double)
1335     {
1336       if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1337     }
1338   else if(inport->edGetType()->kind() == Int)
1339     {
1340       if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1341     }
1342   else if(inport->edGetType()->kind() == String)
1343     {
1344       if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1345     }
1346   else if(inport->edGetType()->kind() == Bool)
1347     {
1348       if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1349     }
1350   else if(inport->edGetType()->kind() == Objref)
1351     {
1352       if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1353     }
1354   else if(inport->edGetType()->kind() == Sequence)
1355     {
1356       if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1357         return new NeutralCorbaSequence(inport);
1358       else
1359         {
1360           stringstream msg;
1361           msg << "Cannot convert this sequence type " ;
1362           msg << __FILE__ << ":" <<__LINE__;
1363           throw ConversionException(msg.str());
1364         }
1365     }
1366   else if(inport->edGetType()->kind() == Struct)
1367     {
1368       if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1369     }
1370
1371   // Adaptation not possible
1372   stringstream msg;
1373   msg << "Cannot connect Neutral output port with type: " << type->id() ;
1374   msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1375 #ifdef _DEVDEBUG_
1376   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1377 #endif
1378   throw ConversionException(msg.str());
1379 }
1380
1381 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1382 /*!
1383  *   \param source : input port to adapt to implementation impl and type type
1384  *   \param impl : output port implementation (C++, Python or Corba)
1385  *   \param type : outport data type 
1386  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1387  *   \return an adaptator port which type depends on impl
1388  */
1389
1390 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1391                                 const std::string& impl,
1392                                 TypeCode * type,bool init)
1393 {
1394   if(impl == CppNode::IMPL_NAME)
1395     {
1396       return adaptCorbaToCpp(source,type);
1397     }
1398   else if(impl == PythonNode::IMPL_NAME)
1399     {
1400       return adaptCorbaToPython(source,type);
1401     }
1402   else if(impl == CORBANode::IMPL_NAME)
1403     {
1404       if(init)
1405         return adaptCorbaToCorba(source,type);
1406       else
1407         return adaptCorbaToCorba(source,type);
1408     }
1409   else if(impl == XmlNode::IMPL_NAME )
1410     {
1411       return adaptCorbaToXml(source,type);
1412     }
1413   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1414     {
1415       return adaptCorbaToNeutral(source,type);
1416     }
1417   else
1418     {
1419       stringstream msg;
1420       msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1421       msg << __FILE__ << ":" <<__LINE__;
1422       throw ConversionException(msg.str());
1423     }
1424 }
1425
1426 //! Adapt a Python input port to a Python output port
1427 /*!
1428  * No need to make conversion or cast. 
1429  * Only check, it's possible.
1430  *   \param inport : InputPort to adapt to Python type type
1431  *   \param type : outport data type 
1432  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1433  *   \return an adaptator port of type InputPyPort 
1434  */
1435
1436 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1437                                               TypeCode * type,bool init)
1438 {
1439   if(init)
1440     return new PyInit(inport);
1441
1442   if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1443     {
1444       //output data is convertible to input type
1445       //With python, no need to convert. Conversion will be done automatically
1446       //by the interpreter
1447       return new ProxyPort(inport);
1448     }
1449   //output data is not convertible to input type
1450   stringstream msg;
1451   msg << "Cannot connect Python output port with type: " << type->id() ;
1452   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1453 #ifdef _DEVDEBUG_
1454   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1455 #endif
1456   throw ConversionException(msg.str());
1457 }
1458
1459 //! Adapt a Python input port to a C++ output port
1460 /*!
1461  *   \param inport : InputPort to adapt to C++ type type
1462  *   \param type : outport data type 
1463  *   \return an adaptator port of C++ type (InputCppPort)
1464  */
1465
1466 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1467                                            TypeCode * type)
1468 {
1469   DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1470   if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1471     {
1472       //output type is convertible to input type
1473       return new CppPy(inport);
1474     }
1475   //output type is not convertible
1476   stringstream msg;
1477   msg << "Cannot connect Cpp output port with type: " << type->id() ;
1478   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1479 #ifdef _DEVDEBUG_
1480   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1481 #endif
1482   throw ConversionException(msg.str());
1483 }
1484
1485 //! Adapt a Python input port to a Neutral data port
1486 /*!
1487  *   \param inport : InputPort to adapt to Neutral type type
1488  *   \param type : outport data type 
1489  *   \return an adaptator port of Neutral type (Neutralxxxx)
1490  */
1491
1492 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1493                                                TypeCode * type)
1494 {
1495   if(inport->edGetType()->kind() == Double)
1496     {
1497       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1498     }
1499   else if(inport->edGetType()->kind() == Int)
1500     {
1501       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1502     }
1503   else if(inport->edGetType()->kind() == String)
1504     {
1505       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1506     }
1507   else if(inport->edGetType()->kind() == Bool)
1508     {
1509       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1510     }
1511   else if(inport->edGetType()->kind() == Objref)
1512     {
1513       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1514     }
1515   else if(inport->edGetType()->kind() == Sequence)
1516     {
1517       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1518         return new NeutralPySequence(inport);
1519       else
1520         {
1521           stringstream msg;
1522           msg << "Cannot convert this sequence type " ;
1523           msg << __FILE__ << ":" <<__LINE__;
1524           throw ConversionException(msg.str());
1525         }
1526     }
1527   else if(inport->edGetType()->kind() == Struct)
1528     {
1529       if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1530     }
1531
1532   // Adaptation not possible
1533   stringstream msg;
1534   msg << "Cannot connect Neutral output port with type: " << type->id() ;
1535   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1536 #ifdef _DEVDEBUG_
1537   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1538 #endif
1539   throw ConversionException(msg.str());
1540 }
1541
1542 //! Adapt a Python input port to a Corba output port
1543 /*!
1544  * Always convert the data
1545  *   \param inport : InputPort to adapt to Corba type type
1546  *   \param type : outport data type 
1547  *   \return an adaptator port of Corba type (InputCorbaPort)
1548  */
1549
1550 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1551                                              TypeCode * type)
1552 {
1553   if(inport->edGetType()->kind() == Double)
1554     {
1555       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1556     }
1557   else if(inport->edGetType()->kind() == Int)
1558     {
1559       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1560     }
1561   else if(inport->edGetType()->kind() == String)
1562     {
1563       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1564     }
1565   else if(inport->edGetType()->kind() == Bool)
1566     {
1567       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1568     }
1569   else if(inport->edGetType()->kind() == Objref)
1570     {
1571       if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1572         {
1573           return new CorbaPyObjref(inport);
1574         }
1575       else
1576         {
1577           stringstream msg;
1578           msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1579           msg << " " << __FILE__ << ":" <<__LINE__;
1580           throw ConversionException(msg.str());
1581         }
1582     }
1583   else if(inport->edGetType()->kind() == Sequence)
1584     {
1585       if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1586         {
1587           return new CorbaPySequence(inport);
1588         }
1589       else
1590         {
1591           stringstream msg;
1592           msg << "Cannot convert this sequence type " ;
1593           msg << __FILE__ << ":" <<__LINE__;
1594           throw ConversionException(msg.str());
1595         }
1596     }
1597   else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1598     {
1599       if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1600         {
1601           return new CorbaPyStruct(inport);
1602         }
1603       else
1604         {
1605           stringstream msg;
1606           msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1607           msg << " " << __FILE__ << ":" <<__LINE__;
1608           throw ConversionException(msg.str());
1609         }
1610     }
1611   // Adaptation not possible
1612   stringstream msg;
1613   msg << "Cannot connect Corba output port with type: " << type->id() ;
1614   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1615 #ifdef _DEVDEBUG_
1616   msg << " ("__FILE__ << ":" << __LINE__ << ")";
1617 #endif
1618   throw ConversionException(msg.str());
1619 }
1620
1621 //! Adapt a Python input port to a Xml output port 
1622 /*!
1623  *   \param inport : input port to adapt to Xml type type
1624  *   \param type : output port type
1625  *   \return an input port of type InputXmlPort
1626  */
1627
1628 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1629                                           TypeCode * type)
1630 {
1631   // BEWARE : using the generic check
1632   if(inport->edGetType()->isAdaptable(type))
1633     {
1634       //convertible type
1635       return new XmlPython(inport);
1636     }
1637   //non convertible type
1638   stringstream msg;
1639   msg << "Cannot connect Xml output port with type: " << type->id() ;
1640   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1641 #ifdef _DEVDEBUG_
1642   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1643 #endif
1644   throw ConversionException(msg.str());
1645 }
1646
1647 //! Adapt a Python input port to an output port with a given implementation
1648 /*!
1649  *   \param source : input port to adapt to implementation impl and type type
1650  *   \param impl : output port implementation (C++, Python or Corba)
1651  *   \param type : output port type
1652  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1653  *   \return     adaptated input port
1654  */
1655
1656 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1657                                 const std::string& impl,
1658                                 TypeCode * type,bool init)
1659 {
1660   if(impl == CppNode::IMPL_NAME)
1661     {
1662       return adaptPythonToCpp(source,type);
1663     }
1664   else if(impl == PythonNode::IMPL_NAME)
1665     {
1666       return adaptPythonToPython(source,type,init);
1667     }
1668   else if(impl == CORBANode::IMPL_NAME)
1669     {
1670       return adaptPythonToCorba(source,type);
1671     }
1672   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1673     {
1674       return adaptPythonToNeutral(source,type);
1675     }
1676   else if(impl == XmlNode::IMPL_NAME)
1677     {
1678       return adaptPythonToXml(source,type);
1679     }
1680   else
1681     {
1682       stringstream msg;
1683       msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1684       msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1685       throw ConversionException(msg.str());
1686     }
1687 }
1688
1689
1690 //! Adapt a C++ input port to connect it to a CORBA output port
1691 /*!
1692  *   \param inport : input port to adapt to CORBA type type
1693  *   \param type : type supported by output port
1694  *   \return an adaptator port of type InputCorbaPort
1695  */
1696
1697 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1698                                           TypeCode * type)
1699 {
1700   DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1701   if(isAdaptableCppCorba(type,inport->edGetType()))
1702     {
1703       //output type is convertible to input type
1704       return new CorbaCpp(inport);
1705     }
1706   //output type is not convertible
1707   stringstream msg;
1708   msg << "Cannot connect Corba output port with type: " << type->id() ;
1709   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1710 #ifdef _DEVDEBUG_
1711   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1712 #endif
1713   throw ConversionException(msg.str());
1714 }
1715
1716 //! Adapt a C++ input port to a Python output port
1717 /*!
1718  *   \param inport : input port to adapt to Python type type
1719  *   \param type : output port type
1720  *   \return an adaptated input port of type InputPyPort
1721  */
1722 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1723                       TypeCode * type)
1724 {
1725   DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1726   if(isAdaptableCppPyObject(type,inport->edGetType()))
1727     {
1728       //output type is convertible to input type
1729       return new PyCpp(inport);
1730     }
1731   //output type is not convertible
1732   stringstream msg;
1733   msg << "Cannot connect Python output port with type: " << type->id() ;
1734   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1735 #ifdef _DEVDEBUG_
1736   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1737 #endif
1738   throw ConversionException(msg.str());
1739 }
1740
1741 //! Adapt a C++ input port to a C++ output port
1742 /*!
1743  *   \param inport : input port to adapt to C++ type type
1744  *   \param type : output port type
1745  *   \return an adaptated input port of type InputPyPort
1746  */
1747 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1748                       TypeCode * type)
1749 {
1750   DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1751   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
1752   if(type->isAdaptable(inport->edGetType()))
1753     {
1754       //the output data is convertible to inport type
1755       return new CppCpp(inport);
1756     }
1757   //non convertible type
1758   stringstream msg;
1759   msg << "Cannot connect Cpp output port with type: " << type->id() ;
1760   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1761 #ifdef _DEVDEBUG_
1762   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1763 #endif
1764   throw ConversionException(msg.str());
1765 }
1766
1767 //! Adapt a C++ input port to a Neutral output port
1768 /*!
1769  *   \param inport : input port to adapt to C++ type type
1770  *   \param type : output port type
1771  *   \return an adaptated input port of type InputPyPort
1772  */
1773 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1774                       TypeCode * type)
1775 {
1776   DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1777   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
1778   if(type->isAdaptable(inport->edGetType()))
1779     {
1780       //the output data is convertible to inport type
1781       return new NeutralCpp(inport);
1782     }
1783   //non convertible type
1784   stringstream msg;
1785   msg << "Cannot connect Neutral output port with type: " << type->id() ;
1786   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1787 #ifdef _DEVDEBUG_
1788   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1789 #endif
1790   throw ConversionException(msg.str());
1791 }
1792
1793 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1794                       TypeCode * type)
1795 {
1796   DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1797   if(isAdaptableCppXml(type,inport->edGetType()))
1798     {
1799       //convertible type
1800       return new XmlCpp(inport);
1801     }
1802   //non convertible type
1803   stringstream msg;
1804   msg << "Cannot connect Xml output port with type: " << type->id() ;
1805   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1806 #ifdef _DEVDEBUG_
1807   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1808 #endif
1809    throw ConversionException(msg.str());
1810 }
1811
1812 //! Adapt a C++ input port to connect it to an output port with a given implementation
1813 /*!
1814  *   \param source : input port to adapt to implementation impl and type type
1815  *   \param impl : output port implementation (C++, Python or Corba)
1816  *   \param type : output port supported type
1817  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1818  *   \return       the adaptated port
1819  */
1820
1821 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1822                                 const std::string& impl,
1823                                 TypeCode * type,bool init)
1824 {
1825   DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1826   if(impl == CORBANode::IMPL_NAME)
1827     {
1828       return adaptCppToCorba(source,type);
1829     }
1830   else if(impl == PythonNode::IMPL_NAME)
1831     {
1832       return adaptCppToPython(source,type);
1833     }
1834   else if(impl == XmlNode::IMPL_NAME)
1835     {
1836       return adaptCppToXml(source,type);
1837     }
1838   else if(impl == CppNode::IMPL_NAME)
1839     {
1840       return adaptCppToCpp(source, type);
1841     }
1842   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1843     {
1844       return adaptCppToNeutral(source, type);
1845     }
1846   else
1847     {
1848       stringstream msg;
1849       msg << "Cannot connect InputCppPort to " << impl << " implementation";
1850       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1851       throw ConversionException(msg.str());
1852     }
1853 }
1854
1855 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort, 
1856 //                               const InputPort*  inputPort)
1857 // {
1858 //   bool result=true;
1859 //   return result;
1860 // }
1861
1862 CORBA::ORB_ptr RuntimeSALOME::getOrb() const
1863 {
1864   return _orb;
1865 }
1866
1867 PyObject * RuntimeSALOME::getPyOrb() const
1868 {
1869   return _pyorb;
1870 }
1871
1872 PyObject * RuntimeSALOME::getBuiltins() const
1873 {
1874   return _bltins;
1875 }
1876
1877 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory() const
1878 {
1879   return _dynFactory;
1880 }
1881
1882 PyObject * RuntimeSALOME::get_omnipy()
1883 {
1884   return _omnipy;
1885 }
1886
1887 omniORBpyAPI* RuntimeSALOME::getApi()
1888 {
1889   return _api;
1890 }
1891
1892 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1893 {
1894   if(data)
1895     return (void *)convertNeutralPyObject(type,data);
1896   else
1897     {
1898       Py_INCREF(Py_None);
1899       return (void *)Py_None;
1900     }
1901 }
1902
1903 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1904 {
1905   PyObject* ob;
1906   if(data)
1907     {
1908       // The call to PyGILState_Ensure was moved here because there was also
1909       // a crash when calling convertNeutralPyObject with a sequence of pyobj.
1910       // see also the comment below.
1911       PyGILState_STATE gstate = PyGILState_Ensure();
1912       ob=convertNeutralPyObject(type,data);
1913       std::string s=convertPyObjectToString(ob);
1914
1915       // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1916       // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1917       // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1918       // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1919       // feel free to change this code.
1920       //PyGILState_STATE gstate = PyGILState_Ensure();
1921       Py_DECREF(ob);
1922       PyGILState_Release(gstate);
1923       return s;
1924     }
1925   else
1926     {
1927       return "None";
1928     }
1929 }
1930
1931 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1932 {
1933   return YACS::ENGINE::convertPyObjectToString(ob);
1934 }
1935
1936 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1937 {
1938   PyObject *mainmod;
1939   PyObject *globals;
1940   PyObject* ob;
1941   PyGILState_STATE gstate = PyGILState_Ensure();
1942   mainmod = PyImport_AddModule("__main__");
1943   globals = PyModule_GetDict(mainmod);
1944   PyObject* d = PyDict_New();
1945   //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1946   ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1947   Py_DECREF(d);
1948   if(ob==NULL)
1949     {
1950       //exception
1951       std::string error;
1952       PyObject* new_stderr = newPyStdOut(error);
1953       PySys_SetObject((char *)"stderr", new_stderr);
1954       PyErr_Print();
1955       PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1956       Py_DECREF(new_stderr);
1957       PyGILState_Release(gstate);
1958       throw Exception(error);
1959     }
1960   PyGILState_Release(gstate);
1961   return ob;
1962 }