Salome HOME
[EDF30062] and [EDF30014] : addition of --activate-custom-overrides parameter in...
[modules/yacs.git] / src / runtime / RuntimeSALOME.cxx
1 // Copyright (C) 2006-2024  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(bool isFinalizingPython)
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       if( isFinalizingPython )
454         Py_Finalize();
455 #ifdef REFCNT
456       DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
457 #endif
458     }
459   else
460     {
461       if (_useCorba)
462         {
463 #ifdef REFCNT
464           DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
465 #endif
466           _orb->destroy();
467         }
468     }
469 }
470
471 PyObject *RuntimeSALOME::launchSubProcess(const std::vector<std::string>& cmds)
472 {
473   std::ostringstream oss; oss << "from subprocess import Popen" << std::endl;
474   oss << "p = Popen([";
475   for(auto i = 0 ; i < cmds.size() ; ++i)
476   {
477     oss << " " << "\"" << cmds[i] << "\"";
478     if(i < cmds.size()-1)
479       oss << ", ";
480     else
481       oss << " ";
482   }
483   oss << "])";
484   AutoGIL agil;
485   AutoPyRef context = PyDict_New();
486   PyDict_SetItemString( context, "__builtins__", getBuiltins() );
487   std::string errorDetails;
488   try
489   {
490     PythonNode::ExecuteLocalInternal(oss.str().c_str(),context,errorDetails);
491   }
492   catch(const YACS::Exception& e)
493   {
494     std::cerr << e.what() << std::endl << errorDetails << std::endl;
495     throw e;
496   }
497   PyObject *ret = PyDict_GetItemString(context,"p");
498   Py_XINCREF(ret);
499   Py_XINCREF(ret);
500   return ret;
501 }
502
503 std::vector< std::pair<std::string,int> > RuntimeSALOME::getCatalogOfComputeNodes() const
504 {
505   CORBA::ORB_ptr orb(getOrb());
506   SALOME_NamingService_Wrapper namingService;
507   try
508   {
509     namingService.init_orb(orb);
510   }
511   catch(SALOME_Exception& e)
512   {
513     throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Unable to contact the SALOME Naming Service");
514   }
515   CORBA::Object_var obj(namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS));
516   if(CORBA::is_nil(obj))
517     throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Unable to access to the resource manager !");
518   Engines::ResourcesManager_var resManager(Engines::ResourcesManager::_narrow(obj));
519   if(CORBA::is_nil(resManager))
520     throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Internal error ! The entry attached to the res manager in NS does not have right type !");
521   std::vector< std::pair<std::string,int> > ret;
522   Engines::ResourceParameters params;
523   params.name = "";
524   params.hostname = "";
525   params.OS = "";
526   params.nb_proc = 0;
527   params.mem_mb = 0;
528   params.cpu_clock = 0;
529   params.nb_node = 0;
530   params.nb_proc_per_node = 0;
531   params.policy = "";
532   params.can_launch_batch_jobs = false;
533   params.can_run_containers = true;
534   params.componentList.length(0);
535   try
536   {
537     Engines::ResourceList_var resourceList;
538     resourceList = resManager->GetFittingResources(params);
539     ret.reserve(resourceList->length());
540     for(int i = 0; i<resourceList->length(); i++)
541     {
542       const char* resource_name = resourceList[i];
543       std::string std_resource_name = resource_name;
544       Engines::ResourceDefinition_var resource_definition
545                               = resManager->GetResourceDefinition(resource_name);
546       int nb_cores = resource_definition->nb_node *
547                      resource_definition->nb_proc_per_node;
548       ret.push_back(std::pair<std::string,int>(resource_name, nb_cores));
549     }
550   }
551   catch(SALOME::SALOME_Exception& e)
552   {
553     std::string message;
554     message=e.details.text.in();
555     throw Exception(message);
556   }
557
558   return ret;
559 }
560
561 std::string RuntimeSALOME::getVersion() const
562 {
563 #ifdef YACS_DEVELOPMENT
564   return CORBA::string_dup(YACS_VERSION_STR"dev");
565 #else
566   return CORBA::string_dup(YACS_VERSION_STR);
567 #endif
568 }
569
570 Proc* RuntimeSALOME::createProc(const std::string& name)
571 {
572   return new SalomeProc(name);
573 }
574
575 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
576                                             std::list<TypeCodeObjref *> ltc)
577 {
578   std::string myName;
579   if(id == "") myName = "IDL:" + name + ":1.0";
580   else myName = id;
581   return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
582 }
583
584 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
585                                            const std::string& name,
586                                            TypeCode *content)
587 {
588   return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
589 };
590
591 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
592 {
593   std::string myName;
594   if(id == "") myName = "IDL:" + name + ":1.0";
595   else myName = id;
596   return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
597 }
598
599 Bloc* RuntimeSALOME::createBloc(const std::string& name)
600 {
601   return new Bloc(name);
602 }
603
604 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
605 {
606   return new WhileLoop(name);
607 }
608
609 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
610 {
611   return new ForLoop(name);
612 }
613
614 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
615                                                   bool algInitOnFile, const std::string& kind, Proc * procForTypes)
616 {
617   OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
618                                           new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
619   ol->edGetNbOfBranchesPort()->edInit(1);
620   return ol;
621 }
622
623 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
624 {
625   DataNode* node;
626   if(kind == "" )
627     {
628       node = new PresetNode(name);
629       return node;
630     }
631   else if(kind == "study" )
632     {
633       return new StudyInNode(name);
634     }
635   std::string msg="DataNode kind ("+kind+") unknown";
636   throw Exception(msg);
637 }
638
639 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
640 {
641   if(kind == "" )
642     {
643       return new OutNode(name);
644     }
645   else if(kind == "study" )
646     {
647       return new StudyOutNode(name);
648     }
649
650   std::string msg="OutDataNode kind ("+kind+") unknown";
651   throw Exception(msg);
652 }
653
654 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
655 {
656   InlineFuncNode* node;
657   if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
658     {
659       node = new PyFuncNode(name);
660       return node;
661     }
662   if(kind == DistributedPythonNode::KIND)
663     return new DistributedPythonNode(name);
664   std::string msg="FuncNode kind ("+kind+") unknown";
665   throw Exception(msg);
666 }
667
668 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
669 {
670   InlineNode* node;
671   if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
672     {
673       node = new PythonNode(name);
674       return node;
675     }
676   std::string msg="ScriptNode kind ("+kind+") unknown";
677   throw Exception(msg);
678 }
679
680 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
681 {
682   ServiceNode* node;
683   if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
684     {
685       node = new CORBANode(name);
686       return node;
687     }
688   else if(kind == XmlNode::KIND)
689     {
690       node = new XmlNode(name);
691       return node;
692     }
693   std::string msg="RefNode kind ("+kind+") unknown";
694   throw Exception(msg);
695 }
696
697 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
698 {
699   ServiceNode* node;
700   if(kind == "" || kind == SalomeNode::KIND )
701     {
702       node=new SalomeNode(name);
703       return node;
704     }
705   else if (kind == CppNode::KIND) 
706     {
707       node = new CppNode(name);
708       return node;
709     }
710   std::string msg="CompoNode kind ("+kind+") unknown";
711   throw Exception(msg);
712 }
713
714 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
715 {
716   if(kind == "" || kind == SalomeNode::KIND )
717     return new SalomePythonNode(name);
718   std::string msg="CompoNode kind ("+kind+") unknown";
719   throw Exception(msg);
720 }
721
722 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
723                                                           const std::string& kind)
724 {
725   ComponentInstance* compo;
726   if(kind == "" || kind == SalomeComponent::KIND) 
727     return new SalomeComponent(name);
728   else if(kind == CORBAComponent::KIND)
729     return new CORBAComponent(name);
730   else if(kind == SalomePythonComponent::KIND)
731     return new SalomePythonComponent(name);
732   else if (kind == CppComponent::KIND)
733     return new CppComponent(name);
734   else if (kind == SalomeHPComponent::KIND)
735     return new SalomeHPComponent(name);
736   std::string msg="Component Instance kind ("+kind+") unknown";
737   throw Exception(msg);
738 }
739
740 Container *RuntimeSALOME::createContainer(const std::string& kind)
741 {
742   if(kind == "" || kind == SalomeContainer::KIND)
743     return new SalomeContainer;
744   if(kind==SalomeHPContainer::KIND)
745     return new SalomeHPContainer;
746   else if (kind == CppContainer::KIND)
747     return new CppContainer;
748   std::string msg="Container kind ("+kind+") unknown";
749   throw Exception(msg);
750 }
751
752 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
753                                            const std::string& impl,
754                                            Node * node,
755                                            TypeCode * type)
756 {
757   if(impl == CppNode::IMPL_NAME)
758     {
759       return new InputCppPort(name, node, type);
760     }
761   else if(impl == PythonNode::IMPL_NAME)
762     {
763       return new InputPyPort(name, node, type);
764     }
765   else if(impl == CORBANode::IMPL_NAME)
766     {
767       return new InputCorbaPort(name, node, type);
768     }
769   else if(impl == XmlNode::IMPL_NAME)
770     {
771       return new InputXmlPort(name, node, type);
772     }
773   else
774     {
775       stringstream msg;
776       msg << "Cannot create " << impl << " InputPort" ;
777       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
778       throw Exception(msg.str());
779     }
780 }
781
782 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
783                                              const std::string& impl,
784                                              Node * node,
785                                              TypeCode * type)
786 {
787   if(impl == CppNode::IMPL_NAME)
788     {
789       return new OutputCppPort(name, node, type);
790     }
791   else if(impl == PythonNode::IMPL_NAME)
792     {
793       return new OutputPyPort(name, node, type);
794     }
795   else if(impl == CORBANode::IMPL_NAME)
796     {
797       return new OutputCorbaPort(name, node, type);
798     }
799   else if(impl == XmlNode::IMPL_NAME)
800     {
801       return new OutputXmlPort(name, node, type);
802     }
803   else
804     {
805       stringstream msg;
806       msg << "Cannot create " << impl << " OutputPort" ;
807       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
808       throw Exception(msg.str());
809     }
810 }
811
812 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
813                                                               Node *node,TypeCode *type)
814 {
815   DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
816   if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
817     {
818       return new InputCalStreamPort(name,node,type);
819     }
820   else
821     {
822       return new InputDataStreamPort(name,node,type);
823     }
824 }
825
826 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
827                                                                 Node *node,TypeCode *type)
828 {
829   DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
830   if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
831     {
832       return new OutputCalStreamPort(name,node,type);
833     }
834   else
835     {
836       return new OutputDataStreamPort(name,node,type);
837     }
838 }
839
840 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation 
841 /*!
842  *  \param source : InputPort to be adapted
843  *  \param impl : new implementation (C++, python, CORBA, XML, Neutral)
844  *  \param type : data type provided by the InputPort
845  *  \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
846  * 
847  * \return : adapted InputPort
848  */
849 InputPort* RuntimeSALOME::adapt(InputPort* source,
850                                 const std::string& impl,
851                                 TypeCode * type,bool init)
852 {
853   string imp_source=source->getNode()->getImplementation();
854   if(imp_source == PythonNode::IMPL_NAME)
855     {
856       return adapt((InputPyPort*)source,impl,type,init);
857     }
858   else if(imp_source == CppNode::IMPL_NAME)
859     {
860       return adapt((InputCppPort*)source,impl,type,init);
861     }
862   else if(imp_source == CORBANode::IMPL_NAME)
863     {
864       return adapt((InputCorbaPort*)source,impl,type,init);
865     }
866   else if(imp_source == XmlNode::IMPL_NAME)
867     {
868       return adapt((InputXmlPort*)source,impl,type,init);
869     }
870   else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
871     {
872       return adaptNeutral(source,impl,type,init);
873     }
874   else
875     {
876       stringstream msg;
877       msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
878       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
879       throw ConversionException(msg.str());
880     }
881 }
882
883 //! Adapter function for InPropertyPort
884 /*!
885  *  \param source : InPropertyPort to be adapted
886  *  \param impl : new implementation (C++, python, CORBA, XML, Neutral)
887  *  \param type : data type provided by the InPropertyPort
888  *  \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
889  * 
890  * \return : adapted InputPort
891  */
892 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
893                                 const std::string& impl,
894                                 TypeCode * type,bool init)
895 {
896   return adaptNeutral((InputPort *)source,impl,type,init);
897 }
898
899 //! Adapt a Neutral input port to a Corba output port
900 /*!
901  *   \param inport : Neutral input port to adapt to Corba type type
902  *   \param type : output port type
903  *   \return an adaptated input port of type InputCorbaPort
904  */
905 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
906                       TypeCode * type)
907 {
908   // BEWARE : using the generic check
909   if(inport->edGetType()->isAdaptable(type))
910     {
911       //the output data is convertible to inport type
912       return new CorbaNeutral(inport);
913     }
914   //non convertible type
915   stringstream msg;
916   msg << "Cannot connect Corba output port with type: " << type->id() ;
917   msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
918 #ifdef _DEVDEBUG_
919   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
920 #endif
921   throw ConversionException(msg.str());
922 }
923
924 //! Adapt a Neutral input port to a Python output port
925 /*!
926  *   \param inport : input port to adapt to Python type type
927  *   \param type : output port type
928  *   \return an adaptated input port of type InputPyPort
929  */
930 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
931                       TypeCode * type)
932 {
933   // BEWARE : using the generic check
934   if(inport->edGetType()->isAdaptable(type))
935     {
936       //convertible type
937       return new PyNeutral(inport);
938     }
939   //last chance : an py output that is seq[objref] can be connected to a neutral input objref (P13268)
940   else if(type->kind()==Sequence && type->contentType()->kind()==Objref && inport->edGetType()->kind()==Objref)
941     {
942       return new PyNeutral(inport);
943     }
944   //non convertible type
945   stringstream msg;
946   msg << "Cannot connect Python output port with type: " << type->id() ;
947   msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
948 #ifdef _DEVDEBUG_
949   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
950 #endif
951   throw ConversionException(msg.str());
952 }
953
954 //! Adapt a Neutral input port to a Xml output port 
955 /*!
956  *   \param inport : input port to adapt to Xml type type
957  *   \param type : output port type
958  *   \return an input port of type InputXmlPort
959  */
960 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
961                       TypeCode * type)
962 {
963   // BEWARE : using the generic check
964   if(inport->edGetType()->isAdaptable(type))
965     {
966       //convertible type
967       return new XmlNeutral(inport);
968     }
969   //non convertible type
970   stringstream msg;
971   msg << "Cannot connect Xml output port with type: " << type->id() ;
972   msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
973 #ifdef _DEVDEBUG_
974   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
975 #endif
976   throw ConversionException(msg.str());
977 }
978
979 //! Adapt a Neutral input port to a C++ output port 
980 /*!
981  *   \param inport : input port to adapt to C++ type type
982  *   \param type : output port type
983  *   \return an input port of type InputCppPort
984  */
985 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
986                       TypeCode * type)
987 {
988   DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
989   if(isAdaptableNeutralCpp(type,inport->edGetType()))
990     {
991       //convertible type
992       return new CppNeutral(inport);
993     }
994   //non convertible type
995   stringstream msg;
996   msg << "Cannot connect Cpp output port with type: " << type->id() ;
997   msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
998 #ifdef _DEVDEBUG_
999   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1000 #endif
1001   throw ConversionException(msg.str());
1002 }
1003
1004 //! Adapt a Neutral input port to connect it to an output port with a given implementation
1005 /*!
1006  *   \param source : Neutral input port to adapt to implementation impl and type type
1007  *   \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
1008  *   \param type : output port supported type
1009  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1010  *   \return       the adaptated port
1011  */
1012 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
1013                                        const std::string& impl,
1014                                        TypeCode * type,bool init)
1015 {
1016   if(impl == CppNode::IMPL_NAME)
1017     {
1018       return adaptNeutralToCpp(source,type);
1019     }
1020   else if(impl == PythonNode::IMPL_NAME)
1021     {
1022       return adaptNeutralToPython(source,type);
1023     }
1024   else if(impl == CORBANode::IMPL_NAME)
1025     {
1026       return adaptNeutralToCorba(source,type);
1027     }
1028   else if(impl == XmlNode::IMPL_NAME )
1029     {
1030       return adaptNeutralToXml(source,type);
1031     }
1032   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1033     {
1034       if(init)
1035         return new NeutralInit(source);
1036       else
1037         return new ProxyPort(source);
1038     }
1039   stringstream msg;
1040   msg << "Cannot connect InputPort : unknown implementation " << impl;
1041   msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
1042   throw ConversionException(msg.str());
1043 }
1044
1045 //! Adapt a XML input port to connect it to a CORBA output port 
1046 /*!
1047  *   \param inport : input port to adapt to CORBA type type
1048  *   \param type : type supported by output port
1049  *   \return an adaptator port of type InputCorbaPort 
1050  */
1051
1052 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
1053                                           TypeCode * type)
1054 {
1055   if(isAdaptableXmlCorba(type,inport->edGetType()))
1056     {
1057       //output type is convertible to input type
1058       return new CorbaXml(inport);
1059     }
1060   //output type is not convertible
1061   stringstream msg;
1062   msg << "Cannot connect Corba output port with type: " << type->id() ;
1063   msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1064 #ifdef _DEVDEBUG_
1065   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1066 #endif
1067   throw ConversionException(msg.str());
1068 }
1069
1070 //! Adapt a XML input port to a Python output port
1071 /*!
1072  *   \param inport : input port to adapt to Python type type
1073  *   \param type : output port type
1074  *   \return an adaptated input port of type InputPyPort
1075  */
1076 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
1077                       TypeCode * type)
1078 {
1079   if(inport->edGetType()->isAdaptable(type))
1080     {
1081       //the output data is convertible to inport type
1082       return new PyXml(inport);
1083     }
1084   //non convertible type
1085   stringstream msg;
1086   msg << "Cannot connect Python output port with type: " << type->id() ;
1087   msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1088 #ifdef _DEVDEBUG_
1089   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1090 #endif
1091   throw ConversionException(msg.str());
1092 }
1093
1094 //! Adapt a XML input port to a C++ output port
1095 /*!
1096  *   \param inport : input port to adapt to C++ type type
1097  *   \param type : output port type
1098  *   \return an adaptated input port of type InputPyPort
1099  */
1100 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
1101                       TypeCode * type)
1102 {
1103   DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
1104   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
1105   if(type->isAdaptable(inport->edGetType()))
1106     {
1107       //the output data is convertible to inport type
1108       return new CppXml(inport);
1109     }
1110   //non convertible type
1111   stringstream msg;
1112   msg << "Cannot connect Cpp output port with type: " << type->id() ;
1113   msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1114 #ifdef _DEVDEBUG_
1115   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1116 #endif
1117   throw ConversionException(msg.str());
1118 }
1119
1120 //! Adapt a XML input port to a Neutral output port
1121 /*!
1122  *   \param inport : input port to adapt to Neutral type type
1123  *   \param type : output port type
1124  *   \return an adaptated input port of type Neutralxxxx
1125  */
1126 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
1127                       TypeCode * type)
1128 {
1129   if(inport->edGetType()->isAdaptable(type))
1130     {
1131       //the output data is convertible to inport type
1132       return new NeutralXml(inport);
1133     }
1134   //non convertible type
1135   stringstream msg;
1136   msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
1137   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1138   throw ConversionException(msg.str());
1139 }
1140
1141 //! Adapt a XML input port to a Xml output port
1142 /*!
1143  *   \param inport : input port to adapt to Xml type type
1144  *   \param type : output port type
1145  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1146  *   \return an adaptated input port of type Xmlxxxx
1147  */
1148 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
1149                       TypeCode * type,bool init)
1150 {
1151   if(init)
1152     return new ProxyPort(inport);
1153
1154   if(inport->edGetType()->isAdaptable(type))
1155     return new ProxyPort(inport);
1156
1157   stringstream msg;
1158   msg << "Cannot connect Xml output port with type: " << type->id() ;
1159   msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1160 #ifdef _DEVDEBUG_
1161   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1162 #endif
1163   throw ConversionException(msg.str());
1164 }
1165
1166 //! Adapt an Xml input port to an output port which implementation is given by impl
1167 /*!
1168  *   \param source : input port to adapt to implementation impl and type type
1169  *   \param impl : output port implementation (C++, Python or Corba)
1170  *   \param type : output port supported type
1171  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1172  *   \return       the adaptated port
1173  */
1174
1175 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1176                                 const std::string& impl,
1177                                 TypeCode * type,bool init)
1178 {
1179   if(impl == CORBANode::IMPL_NAME)
1180     {
1181       return adaptXmlToCorba(source,type);
1182     }
1183   else if(impl == PythonNode::IMPL_NAME)
1184     {
1185       return adaptXmlToPython(source,type);
1186     }
1187   else if(impl == CppNode::IMPL_NAME)
1188     {
1189       return adaptXmlToCpp(source,type);
1190     }
1191   else if(impl == XmlNode::IMPL_NAME )
1192     {
1193       return adaptXmlToXml(source,type,init);
1194     }
1195   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1196     {
1197       return adaptXmlToNeutral(source,type);
1198     }
1199   else
1200     {
1201       stringstream msg;
1202       msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1203       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1204       throw ConversionException(msg.str());
1205     }
1206 }
1207
1208
1209 //! Adapt a CORBA input port to a CORBA output port 
1210 /*!
1211  *   \param inport : input port to adapt to CORBA outport data type
1212  *   \param type : outport data type 
1213  *   \return an adaptator port of type InputCORBAPort 
1214  */
1215 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1216                                             TypeCode * type)
1217 {
1218   if(type->isA(inport->edGetType()))
1219     {
1220       //types are compatible : no conversion 
1221       //outport data type is more specific than inport required type
1222       //so the inport can be used safely 
1223       return new ProxyPort(inport);
1224     }
1225   else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1226     {
1227       //ouport data can be converted to inport data type
1228       return new CorbaCorba(inport);
1229     }
1230   //outport data can not be converted
1231   stringstream msg;
1232   msg << "Cannot connect Corba output port with type: " << type->id() ;
1233   msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1234 #ifdef _DEVDEBUG_
1235   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1236 #endif
1237   throw ConversionException(msg.str());
1238 }
1239
1240 //! Adapt a CORBA input port to a Python output port 
1241 /*!
1242  *   \param inport : input port to adapt to Python type type
1243  *   \param type : outport data type 
1244  *   \return an adaptator port of type InputPyPort 
1245  */
1246
1247 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1248                                              TypeCode * type)
1249 {
1250   if(inport->edGetType()->kind() == Double)
1251     {
1252       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1253     }
1254   else if(inport->edGetType()->kind() == Int)
1255     {
1256       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1257     }
1258   else if(inport->edGetType()->kind() == String)
1259     {
1260       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1261     }
1262   else if(inport->edGetType()->kind() == Bool)
1263     {
1264       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1265     }
1266   else if(inport->edGetType()->kind() == Objref )
1267     {
1268       if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1269         {
1270           return new PyCorbaObjref(inport);
1271         }
1272       else
1273         {
1274           stringstream msg;
1275           msg << "Cannot connect Python output port with type: " << type->id() ;
1276           msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1277           msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1278           throw ConversionException(msg.str());
1279         }
1280     }
1281   else if(inport->edGetType()->kind() == Sequence)
1282     {
1283       if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1284         {
1285           return new PyCorbaSequence(inport);
1286         }
1287       else
1288         {
1289           stringstream msg;
1290           msg << "Cannot convert this sequence type " ;
1291           msg << __FILE__ << ":" <<__LINE__;
1292           throw ConversionException(msg.str());
1293         }
1294     }
1295   else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1296     {
1297       if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1298         {
1299           return new PyCorbaStruct(inport);
1300         }
1301       else
1302         {
1303           stringstream msg;
1304           msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1305           msg << __FILE__ << ":" <<__LINE__;
1306           throw ConversionException(msg.str());
1307         }
1308     }
1309   // Adaptation not possible
1310   stringstream msg;
1311   msg << "Cannot connect Python output port with type: " << type->id() ;
1312   msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1313 #ifdef _DEVDEBUG_
1314   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1315 #endif
1316   throw ConversionException(msg.str());
1317 }
1318
1319 //! Adapt a CORBA input port to connect it to a XML output port 
1320 /*!
1321  *   \param inport : input port to adapt to Xml type type
1322  *   \param type : type supported by output port
1323  *   \return an adaptator port of type InputXmlPort 
1324  */
1325
1326 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1327                                           TypeCode * type)
1328 {
1329   // BEWARE : using the generic check
1330   if(inport->edGetType()->isAdaptable(type))
1331     {
1332       //output type is convertible to input type
1333       return new XmlCorba(inport);
1334     }
1335   //output type is not convertible
1336   stringstream msg;
1337   msg << "Cannot connect Xml output port with type: " << type->id() ;
1338   msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1339 #ifdef _DEVDEBUG_
1340   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1341 #endif
1342   throw ConversionException(msg.str());
1343 }
1344
1345 //! Adapt a CORBA input port to a C++ output port 
1346 /*!
1347  *   \param inport : input port to adapt to C++ type type
1348  *   \param type : outport data type 
1349  *   \return an adaptator port of type InputCPPPort 
1350  */
1351
1352 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1353                                           TypeCode * type)
1354 {
1355   DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1356   if(isAdaptableCorbaCpp(type,inport->edGetType()))
1357     {
1358       //output type is convertible to input type
1359       return new CppCorba(inport);
1360     }
1361   //output type is not convertible
1362   stringstream msg;
1363   msg << "Cannot connect Cpp output port with type: " << type->id() ;
1364   msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1365 #ifdef _DEVDEBUG_
1366   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1367 #endif
1368   throw ConversionException(msg.str());
1369 }
1370
1371 //! Adapt a CORBA input port to a neutral data 
1372 /*!
1373  *   \param inport : InputPort to adapt to Neutral type type
1374  *   \param type : outport data type 
1375  *   \return an adaptator port of type Neutralxxxx
1376  */
1377
1378 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1379                                               TypeCode * type)
1380 {
1381   if(inport->edGetType()->kind() == Double)
1382     {
1383       if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1384     }
1385   else if(inport->edGetType()->kind() == Int)
1386     {
1387       if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1388     }
1389   else if(inport->edGetType()->kind() == String)
1390     {
1391       if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1392     }
1393   else if(inport->edGetType()->kind() == Bool)
1394     {
1395       if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1396     }
1397   else if(inport->edGetType()->kind() == Objref)
1398     {
1399       if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1400     }
1401   else if(inport->edGetType()->kind() == Sequence)
1402     {
1403       if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1404         return new NeutralCorbaSequence(inport);
1405       else
1406         {
1407           stringstream msg;
1408           msg << "Cannot convert this sequence type " ;
1409           msg << __FILE__ << ":" <<__LINE__;
1410           throw ConversionException(msg.str());
1411         }
1412     }
1413   else if(inport->edGetType()->kind() == Struct)
1414     {
1415       if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1416     }
1417
1418   // Adaptation not possible
1419   stringstream msg;
1420   msg << "Cannot connect Neutral output port with type: " << type->id() ;
1421   msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1422 #ifdef _DEVDEBUG_
1423   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1424 #endif
1425   throw ConversionException(msg.str());
1426 }
1427
1428 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1429 /*!
1430  *   \param source : input port to adapt to implementation impl and type type
1431  *   \param impl : output port implementation (C++, Python or Corba)
1432  *   \param type : outport data type 
1433  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1434  *   \return an adaptator port which type depends on impl
1435  */
1436
1437 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1438                                 const std::string& impl,
1439                                 TypeCode * type,bool init)
1440 {
1441   if(impl == CppNode::IMPL_NAME)
1442     {
1443       return adaptCorbaToCpp(source,type);
1444     }
1445   else if(impl == PythonNode::IMPL_NAME)
1446     {
1447       return adaptCorbaToPython(source,type);
1448     }
1449   else if(impl == CORBANode::IMPL_NAME)
1450     {
1451       if(init)
1452         return adaptCorbaToCorba(source,type);
1453       else
1454         return adaptCorbaToCorba(source,type);
1455     }
1456   else if(impl == XmlNode::IMPL_NAME )
1457     {
1458       return adaptCorbaToXml(source,type);
1459     }
1460   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1461     {
1462       return adaptCorbaToNeutral(source,type);
1463     }
1464   else
1465     {
1466       stringstream msg;
1467       msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1468       msg << __FILE__ << ":" <<__LINE__;
1469       throw ConversionException(msg.str());
1470     }
1471 }
1472
1473 //! Adapt a Python input port to a Python output port
1474 /*!
1475  * No need to make conversion or cast. 
1476  * Only check, it's possible.
1477  *   \param inport : InputPort to adapt to Python type type
1478  *   \param type : outport data type 
1479  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1480  *   \return an adaptator port of type InputPyPort 
1481  */
1482
1483 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1484                                               TypeCode * type,bool init)
1485 {
1486   if(init)
1487     return new PyInit(inport);
1488
1489   if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1490     {
1491       //output data is convertible to input type
1492       //With python, no need to convert. Conversion will be done automatically
1493       //by the interpreter
1494       return new ProxyPort(inport);
1495     }
1496   //output data is not convertible to input type
1497   stringstream msg;
1498   msg << "Cannot connect Python output port with type: " << type->id() ;
1499   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1500 #ifdef _DEVDEBUG_
1501   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1502 #endif
1503   throw ConversionException(msg.str());
1504 }
1505
1506 //! Adapt a Python input port to a C++ output port
1507 /*!
1508  *   \param inport : InputPort to adapt to C++ type type
1509  *   \param type : outport data type 
1510  *   \return an adaptator port of C++ type (InputCppPort)
1511  */
1512
1513 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1514                                            TypeCode * type)
1515 {
1516   DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1517   if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1518     {
1519       //output type is convertible to input type
1520       return new CppPy(inport);
1521     }
1522   //output type is not convertible
1523   stringstream msg;
1524   msg << "Cannot connect Cpp output port with type: " << type->id() ;
1525   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1526 #ifdef _DEVDEBUG_
1527   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1528 #endif
1529   throw ConversionException(msg.str());
1530 }
1531
1532 //! Adapt a Python input port to a Neutral data port
1533 /*!
1534  *   \param inport : InputPort to adapt to Neutral type type
1535  *   \param type : outport data type 
1536  *   \return an adaptator port of Neutral type (Neutralxxxx)
1537  */
1538
1539 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1540                                                TypeCode * type)
1541 {
1542   if(inport->edGetType()->kind() == Double)
1543     {
1544       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1545     }
1546   else if(inport->edGetType()->kind() == Int)
1547     {
1548       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1549     }
1550   else if(inport->edGetType()->kind() == String)
1551     {
1552       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1553     }
1554   else if(inport->edGetType()->kind() == Bool)
1555     {
1556       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1557     }
1558   else if(inport->edGetType()->kind() == Objref)
1559     {
1560       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1561     }
1562   else if(inport->edGetType()->kind() == Sequence)
1563     {
1564       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1565         return new NeutralPySequence(inport);
1566       else
1567         {
1568           stringstream msg;
1569           msg << "Cannot convert this sequence type " ;
1570           msg << __FILE__ << ":" <<__LINE__;
1571           throw ConversionException(msg.str());
1572         }
1573     }
1574   else if(inport->edGetType()->kind() == Struct)
1575     {
1576       if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1577     }
1578
1579   // Adaptation not possible
1580   stringstream msg;
1581   msg << "Cannot connect Neutral output port with type: " << type->id() ;
1582   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1583 #ifdef _DEVDEBUG_
1584   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1585 #endif
1586   throw ConversionException(msg.str());
1587 }
1588
1589 //! Adapt a Python input port to a Corba output port
1590 /*!
1591  * Always convert the data
1592  *   \param inport : InputPort to adapt to Corba type type
1593  *   \param type : outport data type 
1594  *   \return an adaptator port of Corba type (InputCorbaPort)
1595  */
1596
1597 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1598                                              TypeCode * type)
1599 {
1600   if(inport->edGetType()->kind() == Double)
1601     {
1602       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1603     }
1604   else if(inport->edGetType()->kind() == Int)
1605     {
1606       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1607     }
1608   else if(inport->edGetType()->kind() == String)
1609     {
1610       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1611     }
1612   else if(inport->edGetType()->kind() == Bool)
1613     {
1614       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1615     }
1616   else if(inport->edGetType()->kind() == Objref)
1617     {
1618       if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1619         {
1620           return new CorbaPyObjref(inport);
1621         }
1622       else
1623         {
1624           stringstream msg;
1625           msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1626           msg << " " << __FILE__ << ":" <<__LINE__;
1627           throw ConversionException(msg.str());
1628         }
1629     }
1630   else if(inport->edGetType()->kind() == Sequence)
1631     {
1632       if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1633         {
1634           return new CorbaPySequence(inport);
1635         }
1636       else
1637         {
1638           stringstream msg;
1639           msg << "Cannot convert this sequence type " ;
1640           msg << __FILE__ << ":" <<__LINE__;
1641           throw ConversionException(msg.str());
1642         }
1643     }
1644   else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1645     {
1646       if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1647         {
1648           return new CorbaPyStruct(inport);
1649         }
1650       else
1651         {
1652           stringstream msg;
1653           msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1654           msg << " " << __FILE__ << ":" <<__LINE__;
1655           throw ConversionException(msg.str());
1656         }
1657     }
1658   // Adaptation not possible
1659   stringstream msg;
1660   msg << "Cannot connect Corba output port with type: " << type->id() ;
1661   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1662 #ifdef _DEVDEBUG_
1663   msg << " ("__FILE__ << ":" << __LINE__ << ")";
1664 #endif
1665   throw ConversionException(msg.str());
1666 }
1667
1668 //! Adapt a Python input port to a Xml output port 
1669 /*!
1670  *   \param inport : input port to adapt to Xml type type
1671  *   \param type : output port type
1672  *   \return an input port of type InputXmlPort
1673  */
1674
1675 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1676                                           TypeCode * type)
1677 {
1678   // BEWARE : using the generic check
1679   if(inport->edGetType()->isAdaptable(type))
1680     {
1681       //convertible type
1682       return new XmlPython(inport);
1683     }
1684   //non convertible type
1685   stringstream msg;
1686   msg << "Cannot connect Xml output port with type: " << type->id() ;
1687   msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1688 #ifdef _DEVDEBUG_
1689   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1690 #endif
1691   throw ConversionException(msg.str());
1692 }
1693
1694 //! Adapt a Python input port to an output port with a given implementation
1695 /*!
1696  *   \param source : input port to adapt to implementation impl and type type
1697  *   \param impl : output port implementation (C++, Python or Corba)
1698  *   \param type : output port type
1699  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1700  *   \return     adaptated input port
1701  */
1702
1703 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1704                                 const std::string& impl,
1705                                 TypeCode * type,bool init)
1706 {
1707   if(impl == CppNode::IMPL_NAME)
1708     {
1709       return adaptPythonToCpp(source,type);
1710     }
1711   else if(impl == PythonNode::IMPL_NAME)
1712     {
1713       return adaptPythonToPython(source,type,init);
1714     }
1715   else if(impl == CORBANode::IMPL_NAME)
1716     {
1717       return adaptPythonToCorba(source,type);
1718     }
1719   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1720     {
1721       return adaptPythonToNeutral(source,type);
1722     }
1723   else if(impl == XmlNode::IMPL_NAME)
1724     {
1725       return adaptPythonToXml(source,type);
1726     }
1727   else
1728     {
1729       stringstream msg;
1730       msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1731       msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1732       throw ConversionException(msg.str());
1733     }
1734 }
1735
1736
1737 //! Adapt a C++ input port to connect it to a CORBA output port
1738 /*!
1739  *   \param inport : input port to adapt to CORBA type type
1740  *   \param type : type supported by output port
1741  *   \return an adaptator port of type InputCorbaPort
1742  */
1743
1744 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1745                                           TypeCode * type)
1746 {
1747   DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1748   if(isAdaptableCppCorba(type,inport->edGetType()))
1749     {
1750       //output type is convertible to input type
1751       return new CorbaCpp(inport);
1752     }
1753   //output type is not convertible
1754   stringstream msg;
1755   msg << "Cannot connect Corba output port with type: " << type->id() ;
1756   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1757 #ifdef _DEVDEBUG_
1758   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1759 #endif
1760   throw ConversionException(msg.str());
1761 }
1762
1763 //! Adapt a C++ input port to a Python output port
1764 /*!
1765  *   \param inport : input port to adapt to Python type type
1766  *   \param type : output port type
1767  *   \return an adaptated input port of type InputPyPort
1768  */
1769 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1770                       TypeCode * type)
1771 {
1772   DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1773   if(isAdaptableCppPyObject(type,inport->edGetType()))
1774     {
1775       //output type is convertible to input type
1776       return new PyCpp(inport);
1777     }
1778   //output type is not convertible
1779   stringstream msg;
1780   msg << "Cannot connect Python output port with type: " << type->id() ;
1781   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1782 #ifdef _DEVDEBUG_
1783   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1784 #endif
1785   throw ConversionException(msg.str());
1786 }
1787
1788 //! Adapt a C++ input port to a C++ output port
1789 /*!
1790  *   \param inport : input port to adapt to C++ type type
1791  *   \param type : output port type
1792  *   \return an adaptated input port of type InputPyPort
1793  */
1794 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1795                       TypeCode * type)
1796 {
1797   DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1798   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
1799   if(type->isAdaptable(inport->edGetType()))
1800     {
1801       //the output data is convertible to inport type
1802       return new CppCpp(inport);
1803     }
1804   //non convertible type
1805   stringstream msg;
1806   msg << "Cannot connect Cpp output port with type: " << type->id() ;
1807   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1808 #ifdef _DEVDEBUG_
1809   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1810 #endif
1811   throw ConversionException(msg.str());
1812 }
1813
1814 //! Adapt a C++ input port to a Neutral output port
1815 /*!
1816  *   \param inport : input port to adapt to C++ type type
1817  *   \param type : output port type
1818  *   \return an adaptated input port of type InputPyPort
1819  */
1820 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1821                       TypeCode * type)
1822 {
1823   DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1824   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
1825   if(type->isAdaptable(inport->edGetType()))
1826     {
1827       //the output data is convertible to inport type
1828       return new NeutralCpp(inport);
1829     }
1830   //non convertible type
1831   stringstream msg;
1832   msg << "Cannot connect Neutral output port with type: " << type->id() ;
1833   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1834 #ifdef _DEVDEBUG_
1835   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1836 #endif
1837   throw ConversionException(msg.str());
1838 }
1839
1840 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1841                       TypeCode * type)
1842 {
1843   DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1844   if(isAdaptableCppXml(type,inport->edGetType()))
1845     {
1846       //convertible type
1847       return new XmlCpp(inport);
1848     }
1849   //non convertible type
1850   stringstream msg;
1851   msg << "Cannot connect Xml output port with type: " << type->id() ;
1852   msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1853 #ifdef _DEVDEBUG_
1854   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1855 #endif
1856    throw ConversionException(msg.str());
1857 }
1858
1859 //! Adapt a C++ input port to connect it to an output port with a given implementation
1860 /*!
1861  *   \param source : input port to adapt to implementation impl and type type
1862  *   \param impl : output port implementation (C++, Python or Corba)
1863  *   \param type : output port supported type
1864  *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1865  *   \return       the adaptated port
1866  */
1867
1868 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1869                                 const std::string& impl,
1870                                 TypeCode * type,bool init)
1871 {
1872   DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1873   if(impl == CORBANode::IMPL_NAME)
1874     {
1875       return adaptCppToCorba(source,type);
1876     }
1877   else if(impl == PythonNode::IMPL_NAME)
1878     {
1879       return adaptCppToPython(source,type);
1880     }
1881   else if(impl == XmlNode::IMPL_NAME)
1882     {
1883       return adaptCppToXml(source,type);
1884     }
1885   else if(impl == CppNode::IMPL_NAME)
1886     {
1887       return adaptCppToCpp(source, type);
1888     }
1889   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1890     {
1891       return adaptCppToNeutral(source, type);
1892     }
1893   else
1894     {
1895       stringstream msg;
1896       msg << "Cannot connect InputCppPort to " << impl << " implementation";
1897       msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1898       throw ConversionException(msg.str());
1899     }
1900 }
1901
1902 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort, 
1903 //                               const InputPort*  inputPort)
1904 // {
1905 //   bool result=true;
1906 //   return result;
1907 // }
1908
1909 CORBA::ORB_ptr RuntimeSALOME::getOrb() const
1910 {
1911   return _orb;
1912 }
1913
1914 /*!
1915  * Retrieve from custom NS the entry. Custom NS is supposed to be hosted in current process.
1916  * This method try to emulate CORBA ns convention : "corbaname:rir:#test.my_context/Echo.Object" is converted into "Echo"
1917  * 
1918  * See Engines::EmbeddedNamingService
1919  */
1920 CORBA::Object_var RuntimeSALOME::getFromNS(const char *entry) const
1921 {
1922   CORBA::Object_var ret;
1923   std::string entryCpp(entry);
1924   if(entryCpp.substr(0,4) == "IOR:")
1925   {
1926     ret = _orb->string_to_object( entry );
1927   }
1928   else
1929   {
1930     auto pos = entryCpp.find_last_of('/');
1931     std::string entry1( entryCpp.substr(pos+1,std::string::npos) );
1932     pos = entry1.find_last_of('.');
1933     std::string entry2( entry1.substr(0,pos) );
1934     Engines::EmbeddedNamingService_var ns = GetEmbeddedNamingService();
1935     std::unique_ptr<Engines::IORType> iorRet( ns->Resolve( entry2.c_str() ) );
1936     auto len = iorRet->length();
1937     std::unique_ptr<char[]> iorTrans(new char[len+1]); iorTrans[len] = '\0';
1938     for(auto i = 0 ; i < len ; ++i) iorTrans[i] = (*iorRet)[i];
1939     ret = _orb->string_to_object(iorTrans.get());
1940   }
1941   return ret;
1942 }
1943
1944 PyObject * RuntimeSALOME::getPyOrb() const
1945 {
1946   return _pyorb;
1947 }
1948
1949 PyObject * RuntimeSALOME::getBuiltins() const
1950 {
1951   return _bltins;
1952 }
1953
1954 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory() const
1955 {
1956   return _dynFactory;
1957 }
1958
1959 PyObject * RuntimeSALOME::get_omnipy()
1960 {
1961   return _omnipy;
1962 }
1963
1964 omniORBpyAPI* RuntimeSALOME::getApi()
1965 {
1966   return _api;
1967 }
1968
1969 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1970 {
1971   if(data)
1972     return (void *)convertNeutralPyObject(type,data);
1973   else
1974     {
1975       Py_INCREF(Py_None);
1976       return (void *)Py_None;
1977     }
1978 }
1979
1980 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1981 {
1982   PyObject* ob;
1983   if(data)
1984     {
1985       // The call to PyGILState_Ensure was moved here because there was also
1986       // a crash when calling convertNeutralPyObject with a sequence of pyobj.
1987       // see also the comment below.
1988       PyGILState_STATE gstate = PyGILState_Ensure();
1989       ob=convertNeutralPyObject(type,data);
1990       std::string s=convertPyObjectToString(ob);
1991
1992       // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1993       // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1994       // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1995       // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1996       // feel free to change this code.
1997       //PyGILState_STATE gstate = PyGILState_Ensure();
1998       Py_DECREF(ob);
1999       PyGILState_Release(gstate);
2000       return s;
2001     }
2002   else
2003     {
2004       return "None";
2005     }
2006 }
2007
2008 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
2009 {
2010   return YACS::ENGINE::convertPyObjectToString(ob);
2011 }
2012
2013 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
2014 {
2015   PyObject *mainmod;
2016   PyObject *globals;
2017   PyObject* ob;
2018   PyGILState_STATE gstate = PyGILState_Ensure();
2019   mainmod = PyImport_AddModule("__main__");
2020   globals = PyModule_GetDict(mainmod);
2021   PyObject* d = PyDict_New();
2022   //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
2023   ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
2024   Py_DECREF(d);
2025   if(ob==NULL)
2026     {
2027       //exception
2028       std::string error;
2029       PyObject* new_stderr = newPyStdOut(error);
2030       PySys_SetObject((char *)"stderr", new_stderr);
2031       PyErr_Print();
2032       PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
2033       Py_DECREF(new_stderr);
2034       PyGILState_Release(gstate);
2035       throw Exception(error);
2036     }
2037   PyGILState_Release(gstate);
2038   return ob;
2039 }