Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / runtime / RuntimeSALOME.cxx
1 //#define REFCNT
2 #ifdef REFCNT
3 #define private public
4 #define protected public
5 #include <omniORB4/CORBA.h>
6 #include <omniORB4/internal/typecode.h>
7 #include <omniORB4/internal/corbaOrb.h>
8 #endif
9
10 #include "yacsconfig.h"
11 #include "RuntimeSALOME.hxx"
12 #include "SALOMEDispatcher.hxx"
13 #include "Proc.hxx"
14 #include "WhileLoop.hxx"
15 #include "ForLoop.hxx"
16 #include "Bloc.hxx"
17 #include "InputPort.hxx"
18 #include "OutputPort.hxx"
19 #include "InputDataStreamPort.hxx"
20 #include "OutputDataStreamPort.hxx"
21 #include "SalomeProc.hxx"
22 //Components
23 #include "CORBAComponent.hxx"
24 #include "SalomeComponent.hxx"
25 #include "SalomePythonComponent.hxx"
26 #include "CppComponent.hxx"
27
28 #include "SalomeContainer.hxx"
29 #include "CppContainer.hxx"
30
31 //Nodes
32 #include "PythonNode.hxx"
33 #include "CORBANode.hxx"
34 #include "XMLNode.hxx"
35 #include "CppNode.hxx"
36 #include "TypeConversions.hxx"
37 #include "SalomePythonNode.hxx"
38 //CORBA proxy ports
39 #include "CORBACORBAConv.hxx"
40 #include "CORBAPythonConv.hxx"
41 #include "CORBAXMLConv.hxx"
42 #include "CORBACppConv.hxx"
43 #include "CORBANeutralConv.hxx"
44
45 //Python proxy ports
46 #include "PythonCORBAConv.hxx"
47 #include "PythonXMLConv.hxx"
48 #include "PythonCppConv.hxx"
49 #include "PythonNeutralConv.hxx"
50
51 //Neutral proxy ports
52 #include "NeutralCORBAConv.hxx"
53 #include "NeutralPythonConv.hxx"
54 #include "NeutralXMLConv.hxx"
55 #include "NeutralCppConv.hxx"
56
57 //C++ proxy ports
58 #include "CppCORBAConv.hxx"
59 #include "CppPythonConv.hxx"
60 #include "CppXMLConv.hxx"
61 #include "CppCppConv.hxx"
62 #include "CppNeutralConv.hxx"
63
64 //XML proxy ports
65 #include "XMLCORBAConv.hxx"
66 #include "XMLPythonConv.hxx"
67 #include "XMLCppConv.hxx"
68 #include "XMLNeutralConv.hxx"
69
70 //Calcium specific ports
71 #include "CalStreamPort.hxx"
72
73 #ifdef SALOME_KERNEL
74 #include "SALOME_NamingService.hxx"
75 #include "SALOME_LifeCycleCORBA.hxx"
76 #endif
77   
78 #include <libxml/parser.h>
79 #include <omniORB4/CORBA.h>
80 #include <iostream>
81 #include <sstream>
82 #include <cassert>
83
84 //#define _DEVDEBUG_
85 #include "YacsTrace.hxx"
86
87 using namespace std;
88 using namespace YACS::ENGINE;
89
90 void RuntimeSALOME::setRuntime(long flags) // singleton creation (not thread safe!)
91 {
92   if (! Runtime::_singleton)
93     {
94       Runtime::_singleton = new RuntimeSALOME(flags);
95     }
96   DEBTRACE("RuntimeSALOME::setRuntime() done !");
97 }
98
99 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
100 {
101   assert(Runtime::_singleton);
102   return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
103 }
104
105 /**
106  *  Singleton creation, initialize converter map
107  */
108   
109 RuntimeSALOME::RuntimeSALOME()
110 {
111   assert(0);
112 }
113
114 RuntimeSALOME::RuntimeSALOME(long flags)
115 {
116   // If all flags (apart the IsPyExt flags) are unset, force them to true
117   if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
118     flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
119           +  RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
120
121   // Salome Nodes implies Corba Nodes
122   if (flags & RuntimeSALOME::UseSalome)
123     flags |= RuntimeSALOME::UseCorba;
124
125   // Corba Nodes implies Python Nodes
126   if (flags & RuntimeSALOME::UseCorba)
127     flags |= RuntimeSALOME::UsePython;
128
129   _useCorba = flags & RuntimeSALOME::UseCorba;
130   _usePython = flags & RuntimeSALOME::UsePython;
131   _useCpp = flags & RuntimeSALOME::UseCpp;
132   _useXml = flags & RuntimeSALOME::UseXml;
133
134   if (_useCpp)    _setOfImplementation.insert(CppNode::IMPL_NAME);
135   if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
136   if (_useCorba)  _setOfImplementation.insert(CORBANode::IMPL_NAME);
137   if (_useXml)    _setOfImplementation.insert(XmlNode::IMPL_NAME);
138   init(flags);
139 }
140
141 RuntimeSALOME::~RuntimeSALOME()
142 {
143 }
144
145 //! CORBA and Python initialization
146 /*!
147  *  \param flags contains several bits
148  *            bit0 (ispyext) true when method is called from Python
149  *                           (Python initialization must not be done!)
150  *            bit1 (UsePython) true if python nodes are needed
151  *            bit1 (UseCorba)  true if CORBA nodes are needed
152  *            bit1 (UseXml)    true if python nodes are needed
153  *            bit1 (UseCpp)    true if C++ nodes are needed
154  *            bit1 (UseSalome) true if Salome nodes are needed
155  *
156  */
157
158 void RuntimeSALOME::init(long flags)
159 {
160   bool ispyext = flags & RuntimeSALOME::IsPyExt;
161   if (_useCorba)
162     {
163       int nbargs = 0; char **args = 0;
164       _orb = CORBA::ORB_init (nbargs, args);
165 #ifdef REFCNT
166       DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
167 #endif
168       CORBA::Object_var obj = _orb->resolve_initial_references("DynAnyFactory");
169       _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
170     }
171
172   if (_usePython)
173     {
174       DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
175
176       // Initialize Python interpreter in embedded mode
177       if (!Py_IsInitialized())
178         {
179           Py_InitializeEx(0); // do not install signal handlers
180           PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
181           PyEval_SaveThread(); /* Release the thread state */
182           //here we do not have the Global Interpreter Lock
183         }
184
185       PyObject *mainmod,*pyapi,*res ;
186       PyObject *globals;
187       PyGILState_STATE gstate;
188       gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
189     
190       mainmod = PyImport_AddModule("__main__");
191       globals = PyModule_GetDict(mainmod);
192       /* globals is a borrowed reference */
193   
194       if (PyDict_GetItemString(globals, "__builtins__") == NULL) 
195         {
196           PyObject *bimod = PyImport_ImportModule("__builtin__");
197           if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
198             Py_FatalError("can't add __builtins__ to __main__");
199           Py_DECREF(bimod);
200         }
201
202       _bltins = PyEval_GetBuiltins();  /* borrowed ref */
203   
204       if (_useCorba)
205         {
206
207           //init section
208           PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy");
209           if (!omnipy)
210             {
211               PyErr_Print();
212               PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
213               goto out;
214             }
215           pyapi = PyObject_GetAttrString(omnipy, (char*)"API");
216           if (!pyapi)
217             {
218               goto out;
219             }
220           _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
221           Py_DECREF(pyapi);
222
223           res=PyRun_String("\n"
224                              "import sys\n"
225                              "sys.path.insert(0,'.')\n"
226                              "from omniORB import CORBA\n"
227                              "from omniORB import any\n"
228                              "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
229                              "#print sys.getrefcount(orb)\n"
230                              "\n",
231                              Py_file_input,globals,globals );
232           if(res == NULL)
233             {
234               PyErr_Print();
235               goto out;
236             }
237           Py_DECREF(res);
238
239           _pyorb = PyDict_GetItemString(globals,"orb");
240           /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
241
242           PyObject *pyany;
243           pyany = PyDict_GetItemString(globals,"any");
244           /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
245
246 #ifdef REFCNT
247           DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
248 #endif
249         }
250       out:
251         PyGILState_Release(gstate); // Release the Global Interpreter Lock
252     }
253 }
254
255 void RuntimeSALOME::fini()
256 {
257   if (_usePython)
258     {
259       PyGILState_STATE gstate = PyGILState_Ensure();
260 #ifdef REFCNT
261       DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
262 #endif
263       PyObject *mainmod, *globals;
264       mainmod = PyImport_AddModule("__main__");
265       globals = PyModule_GetDict(mainmod);
266       if (_useCorba)
267         {
268           PyObject* res;
269           res=PyRun_String("orb.destroy()\n"
270                            "\n",
271                            Py_file_input,globals,globals );
272           if(res == NULL)
273             PyErr_Print();
274           else
275             Py_DECREF(res);
276         }
277       Py_Finalize();
278 #ifdef REFCNT
279       DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
280 #endif
281     }
282   else
283     {
284       if (_useCorba)
285         {
286 #ifdef REFCNT
287           DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
288 #endif
289           _orb->destroy();
290         }
291     }
292 }
293
294 Proc* RuntimeSALOME::createProc(const std::string& name)
295 {
296   return new SalomeProc(name);
297 }
298
299 Bloc* RuntimeSALOME::createBloc(const std::string& name)
300 {
301   return new Bloc(name);
302 }
303
304 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
305 {
306   return new WhileLoop(name);
307 }
308
309 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
310 {
311   return new ForLoop(name);
312 }
313
314 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
315 {
316   InlineFuncNode* node;
317   if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
318     {
319       node = new PyFuncNode(name);
320       return node;
321     }
322   std::string msg="FuncNode kind ("+kind+") unknown";
323   throw Exception(msg);
324 }
325
326 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
327 {
328   InlineNode* node;
329   if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
330     {
331       node = new PythonNode(name);
332       return node;
333     }
334   std::string msg="ScriptNode kind ("+kind+") unknown";
335   throw Exception(msg);
336 }
337
338 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
339 {
340   ServiceNode* node;
341   if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
342     {
343       node = new CORBANode(name);
344       return node;
345     }
346   else if(kind == XmlNode::KIND)
347     {
348       node = new XmlNode(name);
349       return node;
350     }
351   std::string msg="RefNode kind ("+kind+") unknown";
352   throw Exception(msg);
353 }
354
355 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
356 {
357   ServiceNode* node;
358   if(kind == "" || kind == SalomeNode::KIND )
359     {
360       node=new SalomeNode(name);
361       return node;
362     }
363   else if (kind == CppNode::KIND) 
364     {
365       node = new CppNode(name);
366       return node;
367     }
368   std::string msg="CompoNode kind ("+kind+") unknown";
369   throw Exception(msg);
370 }
371
372 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
373 {
374   if(kind == "" || kind == SalomeNode::KIND )
375     return new SalomePythonNode(name);
376   std::string msg="CompoNode kind ("+kind+") unknown";
377   throw Exception(msg);
378 }
379
380 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
381                                                           const std::string& kind)
382 {
383   ComponentInstance* compo;
384   if(kind == "" || kind == SalomeComponent::KIND) 
385     return new SalomeComponent(name);
386   else if(kind == CORBAComponent::KIND)
387     return new CORBAComponent(name);
388   else if(kind == SalomePythonComponent::KIND)
389     return new SalomePythonComponent(name);
390   else if (kind == CppComponent::KIND)
391     return new CppComponent(name);
392   std::string msg="Component Instance kind ("+kind+") unknown";
393   throw Exception(msg);
394 }
395
396 Container *RuntimeSALOME::createContainer(const std::string& kind)
397 {
398   if(kind == "" || kind == SalomeComponent::KIND)
399     return new SalomeContainer;
400   else if (kind == CppComponent::KIND)
401     return new CppContainer;
402   std::string msg="Container kind ("+kind+") unknown";
403   throw Exception(msg);
404 }
405
406 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
407                                            const std::string& impl,
408                                            Node * node,
409                                            TypeCode * type)
410 {
411   if(impl == CppNode::IMPL_NAME)
412     {
413       return new InputCppPort(name, node, type);
414     }
415   else if(impl == PythonNode::IMPL_NAME)
416     {
417       return new InputPyPort(name, node, type);
418     }
419   else if(impl == CORBANode::IMPL_NAME)
420     {
421       return new InputCorbaPort(name, node, type);
422     }
423   else if(impl == XmlNode::IMPL_NAME)
424     {
425       return new InputXmlPort(name, node, type);
426     }
427   else
428     {
429       stringstream msg;
430       msg << "Cannot create " << impl << " InputPort" ;
431       msg << " ("__FILE__ << ":" << __LINE__ << ")";
432       throw Exception(msg.str());
433     }
434 }
435
436 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
437                                              const std::string& impl,
438                                              Node * node,
439                                              TypeCode * type)
440 {
441   if(impl == CppNode::IMPL_NAME)
442     {
443       return new OutputCppPort(name, node, type);
444     }
445   else if(impl == PythonNode::IMPL_NAME)
446     {
447       return new OutputPyPort(name, node, type);
448     }
449   else if(impl == CORBANode::IMPL_NAME)
450     {
451       return new OutputCorbaPort(name, node, type);
452     }
453   else if(impl == XmlNode::IMPL_NAME)
454     {
455       return new OutputXmlPort(name, node, type);
456     }
457   else
458     {
459       stringstream msg;
460       msg << "Cannot create " << impl << " OutputPort" ;
461       msg << " ("__FILE__ << ":" << __LINE__ << ")";
462       throw Exception(msg.str());
463     }
464 }
465
466 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
467                                                               Node *node,TypeCode *type)
468 {
469   DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
470   if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
471     {
472       return new InputCalStreamPort(name,node,type);
473     }
474   else
475     {
476       return new InputDataStreamPort(name,node,type);
477     }
478 }
479
480 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
481                                                                 Node *node,TypeCode *type)
482 {
483   DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
484   if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
485     {
486       return new OutputCalStreamPort(name,node,type);
487     }
488   else
489     {
490       return new OutputDataStreamPort(name,node,type);
491     }
492 }
493
494 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation 
495 /*!
496  *  \param source : InputPort to be adapted
497  *  \param impl : new implementation (C++, python, CORBA, XML, Neutral)
498  *  \param type : data type provided by the InputPort
499  * 
500  * \return : adapted InputPort
501  */
502 InputPort* RuntimeSALOME::adapt(InputPort* source,
503                                 const std::string& impl,
504                                 TypeCode * type) throw (ConversionException)
505 {
506   string imp_source=source->getNode()->getImplementation();
507   if(imp_source == PythonNode::IMPL_NAME)
508     {
509       return adapt((InputPyPort*)source,impl,type);
510     }
511   else if(imp_source == CppNode::IMPL_NAME)
512     {
513       return adapt((InputCppPort*)source,impl,type);
514     }
515   else if(imp_source == CORBANode::IMPL_NAME)
516     {
517       return adapt((InputCorbaPort*)source,impl,type);
518     }
519   else if(imp_source == XmlNode::IMPL_NAME)
520     {
521       return adapt((InputXmlPort*)source,impl,type);
522     }
523   else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
524     {
525       return adaptNeutral(source,impl,type);
526     }
527   else
528     {
529       stringstream msg;
530       msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
531       msg << " ("__FILE__ << ":" << __LINE__ << ")";
532       throw ConversionException(msg.str());
533     }
534 }
535
536 //! Adapt a Neutral input port to a Corba output port
537 /*!
538  *   \param inport : Neutral input port to adapt to Corba type type
539  *   \param type : output port type
540  *   \return an adaptated input port of type InputCorbaPort
541  */
542 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
543                       TypeCode * type) throw (ConversionException)
544 {
545   // BEWARE : using the generic check
546   if(inport->edGetType()->isAdaptable(type))
547     {
548       //the output data is convertible to inport type
549       return new CorbaNeutral(inport);
550     }
551   //non convertible type
552   stringstream msg;
553   msg << "Cannot connect Neutral InputPort to OutputCorbaPort : " ;
554   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
555   throw ConversionException(msg.str());
556 }
557
558 //! Adapt a Neutral input port to a Python output port
559 /*!
560  *   \param inport : input port to adapt to Python type type
561  *   \param type : output port type
562  *   \return an adaptated input port of type InputPyPort
563  */
564 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
565                       TypeCode * type) throw (ConversionException)
566 {
567   // BEWARE : using the generic check
568   if(inport->edGetType()->isAdaptable(type))
569     {
570       //convertible type
571       return new PyNeutral(inport);
572     }
573   //non convertible type
574   stringstream msg;
575   msg << "Cannot connect Neutral InputPort to OutputPyPort : " ;
576   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
577   throw ConversionException(msg.str());
578 }
579
580 //! Adapt a Neutral input port to a Xml output port 
581 /*!
582  *   \param inport : input port to adapt to Xml type type
583  *   \param type : output port type
584  *   \return an input port of type InputXmlPort
585  */
586 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
587                       TypeCode * type) throw (ConversionException)
588 {
589   // BEWARE : using the generic check
590   if(inport->edGetType()->isAdaptable(type))
591     {
592       //convertible type
593       return new XmlNeutral(inport);
594     }
595   //non convertible type
596   stringstream msg;
597   msg << "Cannot connect Neutral InputPort to OutputXmlPort : " ;
598   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
599   throw ConversionException(msg.str());
600 }
601
602 //! Adapt a Neutral input port to a C++ output port 
603 /*!
604  *   \param inport : input port to adapt to C++ type type
605  *   \param type : output port type
606  *   \return an input port of type InputCppPort
607  */
608 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
609                       TypeCode * type) throw (ConversionException)
610 {
611   DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
612   if(isAdaptableNeutralCpp(type,inport->edGetType()))
613     {
614       //convertible type
615       return new CppNeutral(inport);
616     }
617   //non convertible type
618   stringstream msg;
619   msg << "Cannot connect Neutral " << inport->edGetType()->getKindRepr() 
620       << " InputPort to " << type->getKindRepr() << " OutputCppPort : " ;
621   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
622   throw ConversionException(msg.str());
623 }
624
625 //! Adapt a Neutral input port to connect it to an output port with a given implementation
626 /*!
627  *   \param source : Neutral input port to adapt to implementation impl and type type
628  *   \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
629  *   \param type : output port supported type
630  *   \return       the adaptated port
631  */
632 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
633                                        const std::string& impl,
634                                        TypeCode * type) throw (ConversionException)
635 {
636   if(impl == CppNode::IMPL_NAME)
637     {
638       return adaptNeutralToCpp(source,type);
639     }
640   else if(impl == PythonNode::IMPL_NAME)
641     {
642       return adaptNeutralToPython(source,type);
643     }
644   else if(impl == CORBANode::IMPL_NAME)
645     {
646       return adaptNeutralToCorba(source,type);
647     }
648   else if(impl == XmlNode::IMPL_NAME)
649     {
650       return adaptNeutralToXml(source,type);
651     }
652   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
653     {
654       return new ProxyPort(source);
655     }
656   stringstream msg;
657   msg << "Cannot connect InputPort : unknown implementation " << impl;
658   msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
659   throw ConversionException(msg.str());
660 }
661
662 //! Adapt a XML input port to connect it to a CORBA output port 
663 /*!
664  *   \param inport : input port to adapt to CORBA type type
665  *   \param type : type supported by output port
666  *   \return an adaptator port of type InputCorbaPort 
667  */
668
669 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
670                                           TypeCode * type) throw (ConversionException)
671 {
672   if(isAdaptableXmlCorba(type,inport->edGetType()))
673     {
674       //output type is convertible to input type
675       return new CorbaXml(inport);
676     }
677   //output type is not convertible
678   stringstream msg;
679   msg << "Cannot connect InputXmlPort to Corba output port " ;
680   msg << type->id() << " != " << inport->edGetType()->id();
681   msg << " ("__FILE__ << ":" << __LINE__ << ")";
682   throw ConversionException(msg.str());
683 }
684
685 //! Adapt a XML input port to a Python output port
686 /*!
687  *   \param inport : input port to adapt to Python type type
688  *   \param type : output port type
689  *   \return an adaptated input port of type InputPyPort
690  */
691 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
692                       TypeCode * type) throw (ConversionException)
693 {
694   if(inport->edGetType()->isAdaptable(type))
695     {
696       //the output data is convertible to inport type
697       return new PyXml(inport);
698     }
699   //non convertible type
700   stringstream msg;
701   msg << "Cannot connect Xml InputPort to OutputPyPort : " ;
702   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
703   throw ConversionException(msg.str());
704 }
705
706 //! Adapt a XML input port to a C++ output port
707 /*!
708  *   \param inport : input port to adapt to C++ type type
709  *   \param type : output port type
710  *   \return an adaptated input port of type InputPyPort
711  */
712 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
713                       TypeCode * type) throw (ConversionException)
714 {
715   DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
716   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
717   if(type->isAdaptable(inport->edGetType()))
718     {
719       //the output data is convertible to inport type
720       return new CppXml(inport);
721     }
722   //non convertible type
723   stringstream msg;
724   msg << "Cannot connect Xml InputPort to OutputCppPort : " ;
725   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
726   throw ConversionException(msg.str());
727 }
728
729 //! Adapt a XML input port to a Neutral output port
730 /*!
731  *   \param inport : input port to adapt to Neutral type type
732  *   \param type : output port type
733  *   \return an adaptated input port of type Neutralxxxx
734  */
735 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
736                       TypeCode * type) throw (ConversionException)
737 {
738   if(inport->edGetType()->isAdaptable(type))
739     {
740       //the output data is convertible to inport type
741       return new NeutralXml(inport);
742     }
743   //non convertible type
744   stringstream msg;
745   msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
746   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
747   throw ConversionException(msg.str());
748 }
749
750 //! Adapt an Xml input port to an output port which implementation is given by impl
751 /*!
752  *   \param source : input port to adapt to implementation impl and type type
753  *   \param impl : output port implementation (C++, Python or Corba)
754  *   \param type : output port supported type
755  *   \return       the adaptated port
756  */
757
758 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
759                                 const std::string& impl,
760                                 TypeCode * type) throw (ConversionException)
761 {
762   if(impl == CORBANode::IMPL_NAME)
763     {
764       return adaptXmlToCorba(source,type);
765     }
766   else if(impl == PythonNode::IMPL_NAME)
767     {
768       return adaptXmlToPython(source,type);
769     }
770   else if(impl == CppNode::IMPL_NAME)
771     {
772       return adaptXmlToCpp(source,type);
773     }
774   else if(impl == XmlNode::IMPL_NAME)
775     {
776       return new ProxyPort(source);
777     }
778   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
779     {
780       return adaptXmlToNeutral(source,type);
781     }
782   else
783     {
784       stringstream msg;
785       msg << "Cannot connect InputXmlPort to " << impl << " implementation";
786       msg << " ("__FILE__ << ":" << __LINE__ << ")";
787       throw ConversionException(msg.str());
788     }
789 }
790
791
792 //! Adapt a CORBA input port to a CORBA output port 
793 /*!
794  *   \param inport : input port to adapt to CORBA outport data type
795  *   \param type : outport data type 
796  *   \return an adaptator port of type InputCORBAPort 
797  */
798 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
799                                             TypeCode * type) throw (ConversionException)
800 {
801   if(type->isA(inport->edGetType()))
802     {
803       //types are compatible : no conversion 
804       //outport data type is more specific than inport required type
805       //so the inport can be used safely 
806       return new ProxyPort(inport);
807     }
808   else if(isAdaptableCorbaCorba(type,inport->edGetType()))
809     {
810       //ouport data can be converted to inport data type
811       return new CorbaCorba(inport);
812     }
813   //outport data can not be converted
814   stringstream msg;
815   msg << "Cannot connect 2 CorbaPort with non convertible types: " ;
816   msg << type->id() << " != " << inport->edGetType()->id();
817   throw ConversionException(msg.str());
818 }
819
820 //! Adapt a CORBA input port to a Python output port 
821 /*!
822  *   \param inport : input port to adapt to Python type type
823  *   \param type : outport data type 
824  *   \return an adaptator port of type InputPyPort 
825  */
826
827 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
828                                              TypeCode * type) throw (ConversionException)
829 {
830   if(inport->edGetType()->kind() == Double)
831     {
832       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
833     }
834   else if(inport->edGetType()->kind() == Int)
835     {
836       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
837     }
838   else if(inport->edGetType()->kind() == String)
839     {
840       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
841     }
842   else if(inport->edGetType()->kind() == Bool)
843     {
844       if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
845     }
846   else if(inport->edGetType()->kind() == Objref )
847     {
848       if(isAdaptableCorbaPyObject(type,inport->edGetType()))
849         {
850           return new PyCorbaObjref(inport);
851         }
852       else
853         {
854           stringstream msg;
855           msg << "Cannot connect InputPyPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
856           msg << " " << __FILE__ << ":" <<__LINE__;
857           throw ConversionException(msg.str());
858         }
859     }
860   else if(inport->edGetType()->kind() == Sequence)
861     {
862       if(isAdaptableCorbaPyObject(type,inport->edGetType()))
863         {
864           return new PyCorbaSequence(inport);
865         }
866       else
867         {
868           stringstream msg;
869           msg << "Cannot convert this sequence type " ;
870           msg << __FILE__ << ":" <<__LINE__;
871           throw ConversionException(msg.str());
872         }
873     }
874   else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
875     {
876       if(isAdaptableCorbaPyObject(type,inport->edGetType()))
877         {
878           return new PyCorbaStruct(inport);
879         }
880       else
881         {
882           stringstream msg;
883           msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
884           msg << __FILE__ << ":" <<__LINE__;
885           throw ConversionException(msg.str());
886         }
887     }
888   // Adaptation not possible
889   stringstream msg;
890   msg << "Cannot connect InputCorbaPort to Python output " ;
891   msg << __FILE__ << ":" <<__LINE__;
892   throw ConversionException(msg.str());
893 }
894
895 //! Adapt a CORBA input port to connect it to a XML output port 
896 /*!
897  *   \param inport : input port to adapt to Xml type type
898  *   \param type : type supported by output port
899  *   \return an adaptator port of type InputXmlPort 
900  */
901
902 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
903                                           TypeCode * type) throw (ConversionException)
904 {
905   // BEWARE : using the generic check
906   if(inport->edGetType()->isAdaptable(type))
907     {
908       //output type is convertible to input type
909       return new XmlCorba(inport);
910     }
911   //output type is not convertible
912   stringstream msg;
913   msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ;
914   msg << __FILE__ << ":" <<__LINE__;
915   throw ConversionException(msg.str());
916 }
917
918 //! Adapt a CORBA input port to a C++ output port 
919 /*!
920  *   \param inport : input port to adapt to C++ type type
921  *   \param type : outport data type 
922  *   \return an adaptator port of type InputCPPPort 
923  */
924
925 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
926                                           TypeCode * type) throw (ConversionException)
927 {
928   DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
929   if(isAdaptableCorbaCpp(type,inport->edGetType()))
930     {
931       //output type is convertible to input type
932       return new CppCorba(inport);
933     }
934   //output type is not convertible
935   stringstream msg;
936   msg << "Cannot connect InputCorbaPort with OutputCppPort : " ;
937   msg << __FILE__ << ":" <<__LINE__;
938   throw ConversionException(msg.str());
939 }
940
941 //! Adapt a CORBA input port to a neutral data 
942 /*!
943  *   \param inport : InputPort to adapt to Neutral type type
944  *   \param type : outport data type 
945  *   \return an adaptator port of type Neutralxxxx
946  */
947
948 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
949                                               TypeCode * type) throw (ConversionException)
950 {
951   if(inport->edGetType()->kind() == Double)
952     {
953       if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
954     }
955   else if(inport->edGetType()->kind() == Int)
956     {
957       if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
958     }
959   else if(inport->edGetType()->kind() == String)
960     {
961       if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
962     }
963   else if(inport->edGetType()->kind() == Bool)
964     {
965       if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
966     }
967   else if(inport->edGetType()->kind() == Objref)
968     {
969       if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
970     }
971   else if(inport->edGetType()->kind() == Sequence)
972     {
973       if(isAdaptableCorbaNeutral(type,inport->edGetType()))
974         return new NeutralCorbaSequence(inport);
975       else
976         {
977           stringstream msg;
978           msg << "Cannot convert this sequence type " ;
979           msg << __FILE__ << ":" <<__LINE__;
980           throw ConversionException(msg.str());
981         }
982     }
983
984   // Adaptation not possible
985   stringstream msg;
986   msg << "Cannot connect InputCorbaPort to Neutral output " ;
987   msg << __FILE__ << ":" <<__LINE__;
988   throw ConversionException(msg.str());
989 }
990
991 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
992 /*!
993  *   \param source : input port to adapt to implementation impl and type type
994  *   \param impl : output port implementation (C++, Python or Corba)
995  *   \param type : outport data type 
996  *   \return an adaptator port which type depends on impl
997  */
998
999 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1000                                 const std::string& impl,
1001                                 TypeCode * type) throw (ConversionException)
1002 {
1003   if(impl == CppNode::IMPL_NAME)
1004     {
1005       return adaptCorbaToCpp(source,type);
1006     }
1007   else if(impl == PythonNode::IMPL_NAME)
1008     {
1009       return adaptCorbaToPython(source,type);
1010     }
1011   else if(impl == CORBANode::IMPL_NAME)
1012     {
1013       return adaptCorbaToCorba(source,type);
1014     }
1015   else if(impl == XmlNode::IMPL_NAME)
1016     {
1017       return adaptCorbaToXml(source,type);
1018     }
1019   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1020     {
1021       return adaptCorbaToNeutral(source,type);
1022     }
1023   else
1024     {
1025       stringstream msg;
1026       msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1027       msg << __FILE__ << ":" <<__LINE__;
1028       throw ConversionException(msg.str());
1029     }
1030 }
1031
1032 //! Adapt a Python input port to a Python output port
1033 /*!
1034  * No need to make conversion or cast. 
1035  * Only check, it's possible.
1036  *   \param inport : InputPort to adapt to Python type type
1037  *   \param type : outport data type 
1038  *   \return an adaptator port of type InputPyPort 
1039  */
1040
1041 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1042                                               TypeCode * type) throw (ConversionException)
1043 {
1044   if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1045     {
1046       //output data is convertible to input type
1047       //With python, no need to convert. Conversion will be done automatically
1048       //by the interpreter
1049       return new ProxyPort(inport);
1050     }
1051   //output data is not convertible to input type
1052   stringstream msg;
1053   msg << "Cannot connect 2 Python Port with non convertible types: " ;
1054   msg << type->id() << " != " << inport->edGetType()->id();
1055   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1056   throw ConversionException(msg.str());
1057 }
1058
1059 //! Adapt a Python input port to a C++ output port
1060 /*!
1061  *   \param inport : InputPort to adapt to C++ type type
1062  *   \param type : outport data type 
1063  *   \return an adaptator port of C++ type (InputCppPort)
1064  */
1065
1066 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1067                                            TypeCode * type) throw (ConversionException)
1068 {
1069   DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1070   if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1071     {
1072       //output type is convertible to input type
1073       return new CppPy(inport);
1074     }
1075   //output type is not convertible
1076   stringstream msg;
1077   msg << "Cannot connect InputPythonPort with OutputCppPort : " ;
1078   msg << __FILE__ << ":" <<__LINE__;
1079   throw ConversionException(msg.str());
1080 }
1081
1082 //! Adapt a Python input port to a Neutral data port
1083 /*!
1084  *   \param inport : InputPort to adapt to Neutral type type
1085  *   \param type : outport data type 
1086  *   \return an adaptator port of Neutral type (Neutralxxxx)
1087  */
1088
1089 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1090                                                TypeCode * type) throw (ConversionException)
1091 {
1092   if(inport->edGetType()->kind() == Double)
1093     {
1094       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1095     }
1096   else if(inport->edGetType()->kind() == Int)
1097     {
1098       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1099     }
1100   else if(inport->edGetType()->kind() == String)
1101     {
1102       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1103     }
1104   else if(inport->edGetType()->kind() == Bool)
1105     {
1106       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1107     }
1108   else if(inport->edGetType()->kind() == Objref)
1109     {
1110       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1111     }
1112   else if(inport->edGetType()->kind() == Sequence)
1113     {
1114       if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1115         return new NeutralPySequence(inport);
1116       else
1117         {
1118           stringstream msg;
1119           msg << "Cannot convert this sequence type " ;
1120           msg << __FILE__ << ":" <<__LINE__;
1121           throw ConversionException(msg.str());
1122         }
1123     }
1124   // Adaptation not possible
1125   stringstream msg;
1126   msg << "Cannot connect InputPyPort to Neutral output " ;
1127   msg << "Output typeid: " << type->id() << " Input typeid: " << inport->edGetType()->id();
1128   msg << " ("__FILE__ << ":" << __LINE__ << ")";
1129   throw ConversionException(msg.str());
1130 }
1131
1132 //! Adapt a Python input port to a Corba output port
1133 /*!
1134  * Always convert the data
1135  *   \param inport : InputPort to adapt to Corba type type
1136  *   \param type : outport data type 
1137  *   \return an adaptator port of Corba type (InputCorbaPort)
1138  */
1139
1140 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1141                                              TypeCode * type) throw (ConversionException)
1142 {
1143   if(inport->edGetType()->kind() == Double)
1144     {
1145       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1146     }
1147   else if(inport->edGetType()->kind() == Int)
1148     {
1149       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1150     }
1151   else if(inport->edGetType()->kind() == String)
1152     {
1153       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1154     }
1155   else if(inport->edGetType()->kind() == Bool)
1156     {
1157       if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1158     }
1159   else if(inport->edGetType()->kind() == Objref)
1160     {
1161       if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1162         {
1163           return new CorbaPyObjref(inport);
1164         }
1165       else
1166         {
1167           stringstream msg;
1168           msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1169           msg << " " << __FILE__ << ":" <<__LINE__;
1170           throw ConversionException(msg.str());
1171         }
1172     }
1173   else if(inport->edGetType()->kind() == Sequence)
1174     {
1175       if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1176         {
1177           return new CorbaPySequence(inport);
1178         }
1179       else
1180         {
1181           stringstream msg;
1182           msg << "Cannot convert this sequence type " ;
1183           msg << __FILE__ << ":" <<__LINE__;
1184           throw ConversionException(msg.str());
1185         }
1186     }
1187   else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1188     {
1189       if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1190         {
1191           return new CorbaPyStruct(inport);
1192         }
1193       else
1194         {
1195           stringstream msg;
1196           msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1197           msg << " " << __FILE__ << ":" <<__LINE__;
1198           throw ConversionException(msg.str());
1199         }
1200     }
1201   // Adaptation not possible
1202   stringstream msg;
1203   msg << "Cannot connect InputPyPort to Corba output " ;
1204   msg <<  __FILE__ << ":" << __LINE__;
1205   throw ConversionException(msg.str());
1206 }
1207
1208 //! Adapt a Python input port to a Xml output port 
1209 /*!
1210  *   \param inport : input port to adapt to Xml type type
1211  *   \param type : output port type
1212  *   \return an input port of type InputXmlPort
1213  */
1214
1215 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1216                                           TypeCode * type) throw (ConversionException)
1217 {
1218   // BEWARE : using the generic check
1219   if(inport->edGetType()->isAdaptable(type))
1220     {
1221       //convertible type
1222       return new XmlPython(inport);
1223     }
1224   //non convertible type
1225   stringstream msg;
1226   msg << "Cannot connect InputPyPort with OutputXmlPort : " ;
1227   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1228   throw ConversionException(msg.str());
1229 }
1230
1231 //! Adapt a Python input port to an output port with a given implementation
1232 /*!
1233  *   \param source : input port to adapt to implementation impl and type type
1234  *   \param impl : output port implementation (C++, Python or Corba)
1235  *   \param type : output port type
1236  *   \return     adaptated input port
1237  */
1238
1239 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1240                                 const std::string& impl,
1241                                 TypeCode * type) throw (ConversionException)
1242 {
1243   if(impl == CppNode::IMPL_NAME)
1244     {
1245       return adaptPythonToCpp(source,type);
1246     }
1247   else if(impl == PythonNode::IMPL_NAME)
1248     {
1249       return adaptPythonToPython(source,type);
1250     }
1251   else if(impl == CORBANode::IMPL_NAME)
1252     {
1253       return adaptPythonToCorba(source,type);
1254     }
1255   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1256     {
1257       return adaptPythonToNeutral(source,type);
1258     }
1259   else if(impl == XmlNode::IMPL_NAME)
1260     {
1261       return adaptPythonToXml(source,type);
1262     }
1263   else
1264     {
1265       stringstream msg;
1266       msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1267       msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
1268       throw ConversionException(msg.str());
1269     }
1270 }
1271
1272
1273 //! Adapt a C++ input port to connect it to a CORBA output port
1274 /*!
1275  *   \param inport : input port to adapt to CORBA type type
1276  *   \param type : type supported by output port
1277  *   \return an adaptator port of type InputCorbaPort
1278  */
1279
1280 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1281                                           TypeCode * type) throw (ConversionException)
1282 {
1283   DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1284   if(isAdaptableCppCorba(type,inport->edGetType()))
1285     {
1286       //output type is convertible to input type
1287       return new CorbaCpp(inport);
1288     }
1289   //output type is not convertible
1290   stringstream msg;
1291   msg << "Cannot connect InputCppPort to Corba output port " ;
1292   msg << type->id() << " != " << inport->edGetType()->id();
1293   msg << " ("__FILE__ << ":" << __LINE__ << ")";
1294   throw ConversionException(msg.str());
1295 }
1296
1297 //! Adapt a C++ input port to a Python output port
1298 /*!
1299  *   \param inport : input port to adapt to Python type type
1300  *   \param type : output port type
1301  *   \return an adaptated input port of type InputPyPort
1302  */
1303 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1304                       TypeCode * type) throw (ConversionException)
1305 {
1306   DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1307   if(isAdaptableCppPyObject(type,inport->edGetType()))
1308     {
1309       //output type is convertible to input type
1310       return new PyCpp(inport);
1311     }
1312   //output type is not convertible
1313   stringstream msg;
1314   msg << "Cannot connect InputCppPort with OutputPythonPort : " ;
1315   msg << __FILE__ << ":" <<__LINE__;
1316   throw ConversionException(msg.str());
1317 }
1318
1319 //! Adapt a C++ input port to a C++ output port
1320 /*!
1321  *   \param inport : input port to adapt to C++ type type
1322  *   \param type : output port type
1323  *   \return an adaptated input port of type InputPyPort
1324  */
1325 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1326                       TypeCode * type) throw (ConversionException)
1327 {
1328   DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1329   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
1330   if(type->isAdaptable(inport->edGetType()))
1331     {
1332       //the output data is convertible to inport type
1333       return new CppCpp(inport);
1334     }
1335   //non convertible type
1336   stringstream msg;
1337   msg << "Cannot connect Cpp InputPort to OutputCppPort : " ;
1338   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1339   throw ConversionException(msg.str());
1340 }
1341
1342 //! Adapt a C++ input port to a Neutral output port
1343 /*!
1344  *   \param inport : input port to adapt to C++ type type
1345  *   \param type : output port type
1346  *   \return an adaptated input port of type InputPyPort
1347  */
1348 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1349                       TypeCode * type) throw (ConversionException)
1350 {
1351   DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1352   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
1353   if(type->isAdaptable(inport->edGetType()))
1354     {
1355       //the output data is convertible to inport type
1356       return new NeutralCpp(inport);
1357     }
1358   //non convertible type
1359   stringstream msg;
1360   msg << "Cannot connect Cpp InputPort to OutputNeutralPort : " ;
1361   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1362   throw ConversionException(msg.str());
1363 }
1364
1365 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1366                       TypeCode * type) throw (ConversionException)
1367 {
1368    DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1369    if(isAdaptableCppXml(type,inport->edGetType()))
1370    {
1371       //convertible type
1372       return new XmlCpp(inport);
1373    }
1374    //non convertible type
1375    stringstream msg;
1376    msg << "Cannot connect InputCppPort with OutputXmlPort : " ;
1377    msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1378    throw ConversionException(msg.str());
1379 }
1380
1381 //! Adapt a C++ input port to connect it to an output port with a given implementation
1382 /*!
1383  *   \param source : input port to adapt to implementation impl and type type
1384  *   \param impl : output port implementation (C++, Python or Corba)
1385  *   \param type : output port supported type
1386  *   \return       the adaptated port
1387  */
1388
1389 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1390                                 const std::string& impl,
1391                                 TypeCode * type) throw (ConversionException)
1392 {
1393   DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1394   if(impl == CORBANode::IMPL_NAME)
1395     {
1396       return adaptCppToCorba(source,type);
1397     }
1398   else if(impl == PythonNode::IMPL_NAME)
1399     {
1400       return adaptCppToPython(source,type);
1401     }
1402   else if(impl == XmlNode::IMPL_NAME)
1403     {
1404       return adaptCppToXml(source,type);
1405     }
1406   else if(impl == CppNode::IMPL_NAME)
1407     {
1408       return adaptCppToCpp(source, type);
1409     }
1410   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1411     {
1412       return adaptCppToNeutral(source, type);
1413     }
1414   else
1415     {
1416       stringstream msg;
1417       msg << "Cannot connect InputCppPort to " << impl << " implementation";
1418       msg << " ("__FILE__ << ":" << __LINE__ << ")";
1419       throw ConversionException(msg.str());
1420     }
1421 }
1422
1423 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort, 
1424 //                               const InputPort*  inputPort)
1425 // {
1426 //   bool result=true;
1427 //   return result;
1428 // }
1429
1430 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1431 {
1432   return _orb;
1433 }
1434
1435 PyObject * RuntimeSALOME::getPyOrb()
1436 {
1437   return _pyorb;
1438 }
1439
1440 PyObject * RuntimeSALOME::getBuiltins()
1441 {
1442   return _bltins;
1443 }
1444
1445 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1446 {
1447   return _dynFactory;
1448 }
1449
1450 omniORBpyAPI* RuntimeSALOME::getApi()
1451 {
1452   return _api;
1453 }
1454