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