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