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