4 #define protected public
5 #include <omniORB4/CORBA.h>
6 #include <omniORB4/internal/typecode.h>
7 #include <omniORB4/internal/corbaOrb.h>
10 #include "yacsconfig.h"
11 #include "RuntimeSALOME.hxx"
12 #include "SALOMEDispatcher.hxx"
14 #include "WhileLoop.hxx"
15 #include "ForLoop.hxx"
17 #include "InputPort.hxx"
18 #include "OutputPort.hxx"
19 #include "InputDataStreamPort.hxx"
20 #include "OutputDataStreamPort.hxx"
21 #include "SalomeProc.hxx"
23 #include "CORBAComponent.hxx"
24 #include "SalomeComponent.hxx"
25 #include "SalomePythonComponent.hxx"
26 #include "CppComponent.hxx"
28 #include "SalomeContainer.hxx"
29 #include "CppContainer.hxx"
32 #include "PythonNode.hxx"
33 #include "CORBANode.hxx"
34 #include "XMLNode.hxx"
35 #include "CppNode.hxx"
36 #include "TypeConversions.hxx"
37 #include "SalomePythonNode.hxx"
39 #include "CORBACORBAConv.hxx"
40 #include "CORBAPythonConv.hxx"
41 #include "CORBAXMLConv.hxx"
42 #include "CORBACppConv.hxx"
43 #include "CORBANeutralConv.hxx"
46 #include "PythonCORBAConv.hxx"
47 #include "PythonXMLConv.hxx"
48 #include "PythonCppConv.hxx"
49 #include "PythonNeutralConv.hxx"
52 #include "NeutralCORBAConv.hxx"
53 #include "NeutralPythonConv.hxx"
54 #include "NeutralXMLConv.hxx"
55 #include "NeutralCppConv.hxx"
58 #include "CppCORBAConv.hxx"
59 #include "CppPythonConv.hxx"
60 #include "CppXMLConv.hxx"
61 #include "CppCppConv.hxx"
62 #include "CppNeutralConv.hxx"
65 #include "XMLCORBAConv.hxx"
66 #include "XMLPythonConv.hxx"
67 #include "XMLCppConv.hxx"
68 #include "XMLNeutralConv.hxx"
70 //Calcium specific ports
71 #include "CalStreamPort.hxx"
74 #include "SALOME_NamingService.hxx"
75 #include "SALOME_LifeCycleCORBA.hxx"
78 #include <libxml/parser.h>
79 #include <omniORB4/CORBA.h>
85 #include "YacsTrace.hxx"
88 using namespace YACS::ENGINE;
90 void RuntimeSALOME::setRuntime(long flags) // singleton creation (not thread safe!)
92 if (! Runtime::_singleton)
94 Runtime::_singleton = new RuntimeSALOME(flags);
96 DEBTRACE("RuntimeSALOME::setRuntime() done !");
99 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
101 assert(Runtime::_singleton);
102 return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
106 * Singleton creation, initialize converter map
109 RuntimeSALOME::RuntimeSALOME()
114 RuntimeSALOME::RuntimeSALOME(long flags)
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;
121 // Salome Nodes implies Corba Nodes
122 if (flags & RuntimeSALOME::UseSalome)
123 flags |= RuntimeSALOME::UseCorba;
125 // Corba Nodes implies Python Nodes
126 if (flags & RuntimeSALOME::UseCorba)
127 flags |= RuntimeSALOME::UsePython;
129 _useCorba = flags & RuntimeSALOME::UseCorba;
130 _usePython = flags & RuntimeSALOME::UsePython;
131 _useCpp = flags & RuntimeSALOME::UseCpp;
132 _useXml = flags & RuntimeSALOME::UseXml;
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);
141 RuntimeSALOME::~RuntimeSALOME()
145 //! CORBA and Python initialization
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
158 void RuntimeSALOME::init(long flags)
160 bool ispyext = flags & RuntimeSALOME::IsPyExt;
163 int nbargs = 0; char **args = 0;
164 _orb = CORBA::ORB_init (nbargs, args);
166 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
168 CORBA::Object_var obj = _orb->resolve_initial_references("DynAnyFactory");
169 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
174 DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
176 // Initialize Python interpreter in embedded mode
177 if (!Py_IsInitialized())
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
185 PyObject *mainmod,*pyapi,*res ;
187 PyGILState_STATE gstate;
188 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
190 mainmod = PyImport_AddModule("__main__");
191 globals = PyModule_GetDict(mainmod);
192 /* globals is a borrowed reference */
194 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
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__");
202 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
208 PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy");
212 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
215 pyapi = PyObject_GetAttrString(omnipy, (char*)"API");
220 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
223 res=PyRun_String("\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"
231 Py_file_input,globals,globals );
239 _pyorb = PyDict_GetItemString(globals,"orb");
240 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
243 pyany = PyDict_GetItemString(globals,"any");
244 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
247 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
251 PyGILState_Release(gstate); // Release the Global Interpreter Lock
255 void RuntimeSALOME::fini()
259 PyGILState_STATE gstate = PyGILState_Ensure();
261 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
263 PyObject *mainmod, *globals;
264 mainmod = PyImport_AddModule("__main__");
265 globals = PyModule_GetDict(mainmod);
269 res=PyRun_String("orb.destroy()\n"
271 Py_file_input,globals,globals );
279 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
287 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
294 Proc* RuntimeSALOME::createProc(const std::string& name)
296 return new SalomeProc(name);
299 Bloc* RuntimeSALOME::createBloc(const std::string& name)
301 return new Bloc(name);
304 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
306 return new WhileLoop(name);
309 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
311 return new ForLoop(name);
314 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
316 InlineFuncNode* node;
317 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
319 node = new PyFuncNode(name);
322 std::string msg="FuncNode kind ("+kind+") unknown";
323 throw Exception(msg);
326 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
329 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
331 node = new PythonNode(name);
334 std::string msg="ScriptNode kind ("+kind+") unknown";
335 throw Exception(msg);
338 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
341 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
343 node = new CORBANode(name);
346 else if(kind == XmlNode::KIND)
348 node = new XmlNode(name);
351 std::string msg="RefNode kind ("+kind+") unknown";
352 throw Exception(msg);
355 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
358 if(kind == "" || kind == SalomeNode::KIND )
360 node=new SalomeNode(name);
363 else if (kind == CppNode::KIND)
365 node = new CppNode(name);
368 std::string msg="CompoNode kind ("+kind+") unknown";
369 throw Exception(msg);
372 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
374 if(kind == "" || kind == SalomeNode::KIND )
375 return new SalomePythonNode(name);
376 std::string msg="CompoNode kind ("+kind+") unknown";
377 throw Exception(msg);
380 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
381 const std::string& kind)
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);
396 Container *RuntimeSALOME::createContainer(const std::string& kind)
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);
406 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
407 const std::string& impl,
411 if(impl == CppNode::IMPL_NAME)
413 return new InputCppPort(name, node, type);
415 else if(impl == PythonNode::IMPL_NAME)
417 return new InputPyPort(name, node, type);
419 else if(impl == CORBANode::IMPL_NAME)
421 return new InputCorbaPort(name, node, type);
423 else if(impl == XmlNode::IMPL_NAME)
425 return new InputXmlPort(name, node, type);
430 msg << "Cannot create " << impl << " InputPort" ;
431 msg << " ("__FILE__ << ":" << __LINE__ << ")";
432 throw Exception(msg.str());
436 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
437 const std::string& impl,
441 if(impl == CppNode::IMPL_NAME)
443 return new OutputCppPort(name, node, type);
445 else if(impl == PythonNode::IMPL_NAME)
447 return new OutputPyPort(name, node, type);
449 else if(impl == CORBANode::IMPL_NAME)
451 return new OutputCorbaPort(name, node, type);
453 else if(impl == XmlNode::IMPL_NAME)
455 return new OutputXmlPort(name, node, type);
460 msg << "Cannot create " << impl << " OutputPort" ;
461 msg << " ("__FILE__ << ":" << __LINE__ << ")";
462 throw Exception(msg.str());
466 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
467 Node *node,TypeCode *type)
469 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
470 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
472 return new InputCalStreamPort(name,node,type);
476 return new InputDataStreamPort(name,node,type);
480 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
481 Node *node,TypeCode *type)
483 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
484 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
486 return new OutputCalStreamPort(name,node,type);
490 return new OutputDataStreamPort(name,node,type);
494 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
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
500 * \return : adapted InputPort
502 InputPort* RuntimeSALOME::adapt(InputPort* source,
503 const std::string& impl,
504 TypeCode * type) throw (ConversionException)
506 string imp_source=source->getNode()->getImplementation();
507 if(imp_source == PythonNode::IMPL_NAME)
509 return adapt((InputPyPort*)source,impl,type);
511 else if(imp_source == CppNode::IMPL_NAME)
513 return adapt((InputCppPort*)source,impl,type);
515 else if(imp_source == CORBANode::IMPL_NAME)
517 return adapt((InputCorbaPort*)source,impl,type);
519 else if(imp_source == XmlNode::IMPL_NAME)
521 return adapt((InputXmlPort*)source,impl,type);
523 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
525 return adaptNeutral(source,impl,type);
530 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
531 msg << " ("__FILE__ << ":" << __LINE__ << ")";
532 throw ConversionException(msg.str());
536 //! Adapt a Neutral input port to a Corba output port
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
542 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
543 TypeCode * type) throw (ConversionException)
545 // BEWARE : using the generic check
546 if(inport->edGetType()->isAdaptable(type))
548 //the output data is convertible to inport type
549 return new CorbaNeutral(inport);
551 //non convertible type
553 msg << "Cannot connect Neutral InputPort to OutputCorbaPort : " ;
554 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
555 throw ConversionException(msg.str());
558 //! Adapt a Neutral input port to a Python output port
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
564 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
565 TypeCode * type) throw (ConversionException)
567 // BEWARE : using the generic check
568 if(inport->edGetType()->isAdaptable(type))
571 return new PyNeutral(inport);
573 //non convertible type
575 msg << "Cannot connect Neutral InputPort to OutputPyPort : " ;
576 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
577 throw ConversionException(msg.str());
580 //! Adapt a Neutral input port to a Xml output port
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
586 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
587 TypeCode * type) throw (ConversionException)
589 // BEWARE : using the generic check
590 if(inport->edGetType()->isAdaptable(type))
593 return new XmlNeutral(inport);
595 //non convertible type
597 msg << "Cannot connect Neutral InputPort to OutputXmlPort : " ;
598 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
599 throw ConversionException(msg.str());
602 //! Adapt a Neutral input port to a C++ output port
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
608 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
609 TypeCode * type) throw (ConversionException)
611 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
612 if(isAdaptableNeutralCpp(type,inport->edGetType()))
615 return new CppNeutral(inport);
617 //non convertible type
619 msg << "Cannot connect Neutral " << inport->edGetType()->getKindRepr()
620 << " InputPort to " << type->getKindRepr() << " OutputCppPort : " ;
621 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
622 throw ConversionException(msg.str());
625 //! Adapt a Neutral input port to connect it to an output port with a given implementation
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
632 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
633 const std::string& impl,
634 TypeCode * type) throw (ConversionException)
636 if(impl == CppNode::IMPL_NAME)
638 return adaptNeutralToCpp(source,type);
640 else if(impl == PythonNode::IMPL_NAME)
642 return adaptNeutralToPython(source,type);
644 else if(impl == CORBANode::IMPL_NAME)
646 return adaptNeutralToCorba(source,type);
648 else if(impl == XmlNode::IMPL_NAME)
650 return adaptNeutralToXml(source,type);
652 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
654 return new ProxyPort(source);
657 msg << "Cannot connect InputPort : unknown implementation " << impl;
658 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
659 throw ConversionException(msg.str());
662 //! Adapt a XML input port to connect it to a CORBA output port
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
669 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
670 TypeCode * type) throw (ConversionException)
672 if(isAdaptableXmlCorba(type,inport->edGetType()))
674 //output type is convertible to input type
675 return new CorbaXml(inport);
677 //output type is not convertible
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());
685 //! Adapt a XML input port to a Python output port
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
691 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
692 TypeCode * type) throw (ConversionException)
694 if(inport->edGetType()->isAdaptable(type))
696 //the output data is convertible to inport type
697 return new PyXml(inport);
699 //non convertible type
701 msg << "Cannot connect Xml InputPort to OutputPyPort : " ;
702 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
703 throw ConversionException(msg.str());
706 //! Adapt a XML input port to a C++ output port
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
712 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
713 TypeCode * type) throw (ConversionException)
715 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
716 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
717 if(type->isAdaptable(inport->edGetType()))
719 //the output data is convertible to inport type
720 return new CppXml(inport);
722 //non convertible type
724 msg << "Cannot connect Xml InputPort to OutputCppPort : " ;
725 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
726 throw ConversionException(msg.str());
729 //! Adapt a XML input port to a Neutral output port
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
735 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
736 TypeCode * type) throw (ConversionException)
738 if(inport->edGetType()->isAdaptable(type))
740 //the output data is convertible to inport type
741 return new NeutralXml(inport);
743 //non convertible type
745 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
746 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
747 throw ConversionException(msg.str());
750 //! Adapt an Xml input port to an output port which implementation is given by impl
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
758 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
759 const std::string& impl,
760 TypeCode * type) throw (ConversionException)
762 if(impl == CORBANode::IMPL_NAME)
764 return adaptXmlToCorba(source,type);
766 else if(impl == PythonNode::IMPL_NAME)
768 return adaptXmlToPython(source,type);
770 else if(impl == CppNode::IMPL_NAME)
772 return adaptXmlToCpp(source,type);
774 else if(impl == XmlNode::IMPL_NAME)
776 return new ProxyPort(source);
778 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
780 return adaptXmlToNeutral(source,type);
785 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
786 msg << " ("__FILE__ << ":" << __LINE__ << ")";
787 throw ConversionException(msg.str());
792 //! Adapt a CORBA input port to a CORBA output port
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
798 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
799 TypeCode * type) throw (ConversionException)
801 if(type->isA(inport->edGetType()))
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);
808 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
810 //ouport data can be converted to inport data type
811 return new CorbaCorba(inport);
813 //outport data can not be converted
815 msg << "Cannot connect 2 CorbaPort with non convertible types: " ;
816 msg << type->id() << " != " << inport->edGetType()->id();
817 throw ConversionException(msg.str());
820 //! Adapt a CORBA input port to a Python output port
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
827 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
828 TypeCode * type) throw (ConversionException)
830 if(inport->edGetType()->kind() == Double)
832 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
834 else if(inport->edGetType()->kind() == Int)
836 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
838 else if(inport->edGetType()->kind() == String)
840 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
842 else if(inport->edGetType()->kind() == Bool)
844 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
846 else if(inport->edGetType()->kind() == Objref )
848 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
850 return new PyCorbaObjref(inport);
855 msg << "Cannot connect InputPyPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
856 msg << " " << __FILE__ << ":" <<__LINE__;
857 throw ConversionException(msg.str());
860 else if(inport->edGetType()->kind() == Sequence)
862 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
864 return new PyCorbaSequence(inport);
869 msg << "Cannot convert this sequence type " ;
870 msg << __FILE__ << ":" <<__LINE__;
871 throw ConversionException(msg.str());
874 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
876 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
878 return new PyCorbaStruct(inport);
883 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
884 msg << __FILE__ << ":" <<__LINE__;
885 throw ConversionException(msg.str());
888 // Adaptation not possible
890 msg << "Cannot connect InputCorbaPort to Python output " ;
891 msg << __FILE__ << ":" <<__LINE__;
892 throw ConversionException(msg.str());
895 //! Adapt a CORBA input port to connect it to a XML output port
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
902 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
903 TypeCode * type) throw (ConversionException)
905 // BEWARE : using the generic check
906 if(inport->edGetType()->isAdaptable(type))
908 //output type is convertible to input type
909 return new XmlCorba(inport);
911 //output type is not convertible
913 msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ;
914 msg << __FILE__ << ":" <<__LINE__;
915 throw ConversionException(msg.str());
918 //! Adapt a CORBA input port to a C++ output port
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
925 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
926 TypeCode * type) throw (ConversionException)
928 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
929 if(isAdaptableCorbaCpp(type,inport->edGetType()))
931 //output type is convertible to input type
932 return new CppCorba(inport);
934 //output type is not convertible
936 msg << "Cannot connect InputCorbaPort with OutputCppPort : " ;
937 msg << __FILE__ << ":" <<__LINE__;
938 throw ConversionException(msg.str());
941 //! Adapt a CORBA input port to a neutral data
943 * \param inport : InputPort to adapt to Neutral type type
944 * \param type : outport data type
945 * \return an adaptator port of type Neutralxxxx
948 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
949 TypeCode * type) throw (ConversionException)
951 if(inport->edGetType()->kind() == Double)
953 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
955 else if(inport->edGetType()->kind() == Int)
957 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
959 else if(inport->edGetType()->kind() == String)
961 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
963 else if(inport->edGetType()->kind() == Bool)
965 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
967 else if(inport->edGetType()->kind() == Objref)
969 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
971 else if(inport->edGetType()->kind() == Sequence)
973 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
974 return new NeutralCorbaSequence(inport);
978 msg << "Cannot convert this sequence type " ;
979 msg << __FILE__ << ":" <<__LINE__;
980 throw ConversionException(msg.str());
984 // Adaptation not possible
986 msg << "Cannot connect InputCorbaPort to Neutral output " ;
987 msg << __FILE__ << ":" <<__LINE__;
988 throw ConversionException(msg.str());
991 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
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
999 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1000 const std::string& impl,
1001 TypeCode * type) throw (ConversionException)
1003 if(impl == CppNode::IMPL_NAME)
1005 return adaptCorbaToCpp(source,type);
1007 else if(impl == PythonNode::IMPL_NAME)
1009 return adaptCorbaToPython(source,type);
1011 else if(impl == CORBANode::IMPL_NAME)
1013 return adaptCorbaToCorba(source,type);
1015 else if(impl == XmlNode::IMPL_NAME)
1017 return adaptCorbaToXml(source,type);
1019 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1021 return adaptCorbaToNeutral(source,type);
1026 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1027 msg << __FILE__ << ":" <<__LINE__;
1028 throw ConversionException(msg.str());
1032 //! Adapt a Python input port to a Python output port
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
1041 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1042 TypeCode * type) throw (ConversionException)
1044 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
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);
1051 //output data is not convertible to input type
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());
1059 //! Adapt a Python input port to a C++ output port
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)
1066 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1067 TypeCode * type) throw (ConversionException)
1069 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1070 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1072 //output type is convertible to input type
1073 return new CppPy(inport);
1075 //output type is not convertible
1077 msg << "Cannot connect InputPythonPort with OutputCppPort : " ;
1078 msg << __FILE__ << ":" <<__LINE__;
1079 throw ConversionException(msg.str());
1082 //! Adapt a Python input port to a Neutral data port
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)
1089 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1090 TypeCode * type) throw (ConversionException)
1092 if(inport->edGetType()->kind() == Double)
1094 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1096 else if(inport->edGetType()->kind() == Int)
1098 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1100 else if(inport->edGetType()->kind() == String)
1102 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1104 else if(inport->edGetType()->kind() == Bool)
1106 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1108 else if(inport->edGetType()->kind() == Objref)
1110 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1112 else if(inport->edGetType()->kind() == Sequence)
1114 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1115 return new NeutralPySequence(inport);
1119 msg << "Cannot convert this sequence type " ;
1120 msg << __FILE__ << ":" <<__LINE__;
1121 throw ConversionException(msg.str());
1124 // Adaptation not possible
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());
1132 //! Adapt a Python input port to a Corba output port
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)
1140 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1141 TypeCode * type) throw (ConversionException)
1143 if(inport->edGetType()->kind() == Double)
1145 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1147 else if(inport->edGetType()->kind() == Int)
1149 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1151 else if(inport->edGetType()->kind() == String)
1153 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1155 else if(inport->edGetType()->kind() == Bool)
1157 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1159 else if(inport->edGetType()->kind() == Objref)
1161 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1163 return new CorbaPyObjref(inport);
1168 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1169 msg << " " << __FILE__ << ":" <<__LINE__;
1170 throw ConversionException(msg.str());
1173 else if(inport->edGetType()->kind() == Sequence)
1175 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1177 return new CorbaPySequence(inport);
1182 msg << "Cannot convert this sequence type " ;
1183 msg << __FILE__ << ":" <<__LINE__;
1184 throw ConversionException(msg.str());
1187 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1189 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1191 return new CorbaPyStruct(inport);
1196 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1197 msg << " " << __FILE__ << ":" <<__LINE__;
1198 throw ConversionException(msg.str());
1201 // Adaptation not possible
1203 msg << "Cannot connect InputPyPort to Corba output " ;
1204 msg << __FILE__ << ":" << __LINE__;
1205 throw ConversionException(msg.str());
1208 //! Adapt a Python input port to a Xml output port
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
1215 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1216 TypeCode * type) throw (ConversionException)
1218 // BEWARE : using the generic check
1219 if(inport->edGetType()->isAdaptable(type))
1222 return new XmlPython(inport);
1224 //non convertible type
1226 msg << "Cannot connect InputPyPort with OutputXmlPort : " ;
1227 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1228 throw ConversionException(msg.str());
1231 //! Adapt a Python input port to an output port with a given implementation
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
1239 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1240 const std::string& impl,
1241 TypeCode * type) throw (ConversionException)
1243 if(impl == CppNode::IMPL_NAME)
1245 return adaptPythonToCpp(source,type);
1247 else if(impl == PythonNode::IMPL_NAME)
1249 return adaptPythonToPython(source,type);
1251 else if(impl == CORBANode::IMPL_NAME)
1253 return adaptPythonToCorba(source,type);
1255 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1257 return adaptPythonToNeutral(source,type);
1259 else if(impl == XmlNode::IMPL_NAME)
1261 return adaptPythonToXml(source,type);
1266 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1267 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1268 throw ConversionException(msg.str());
1273 //! Adapt a C++ input port to connect it to a CORBA output port
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
1280 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1281 TypeCode * type) throw (ConversionException)
1283 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1284 if(isAdaptableCppCorba(type,inport->edGetType()))
1286 //output type is convertible to input type
1287 return new CorbaCpp(inport);
1289 //output type is not convertible
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());
1297 //! Adapt a C++ input port to a Python output port
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
1303 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1304 TypeCode * type) throw (ConversionException)
1306 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1307 if(isAdaptableCppPyObject(type,inport->edGetType()))
1309 //output type is convertible to input type
1310 return new PyCpp(inport);
1312 //output type is not convertible
1314 msg << "Cannot connect InputCppPort with OutputPythonPort : " ;
1315 msg << __FILE__ << ":" <<__LINE__;
1316 throw ConversionException(msg.str());
1319 //! Adapt a C++ input port to a C++ output port
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
1325 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1326 TypeCode * type) throw (ConversionException)
1328 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1329 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1330 if(type->isAdaptable(inport->edGetType()))
1332 //the output data is convertible to inport type
1333 return new CppCpp(inport);
1335 //non convertible type
1337 msg << "Cannot connect Cpp InputPort to OutputCppPort : " ;
1338 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1339 throw ConversionException(msg.str());
1342 //! Adapt a C++ input port to a Neutral output port
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
1348 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1349 TypeCode * type) throw (ConversionException)
1351 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1352 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1353 if(type->isAdaptable(inport->edGetType()))
1355 //the output data is convertible to inport type
1356 return new NeutralCpp(inport);
1358 //non convertible type
1360 msg << "Cannot connect Cpp InputPort to OutputNeutralPort : " ;
1361 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1362 throw ConversionException(msg.str());
1365 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1366 TypeCode * type) throw (ConversionException)
1368 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1369 if(isAdaptableCppXml(type,inport->edGetType()))
1372 return new XmlCpp(inport);
1374 //non convertible type
1376 msg << "Cannot connect InputCppPort with OutputXmlPort : " ;
1377 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1378 throw ConversionException(msg.str());
1381 //! Adapt a C++ input port to connect it to an output port with a given implementation
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
1389 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1390 const std::string& impl,
1391 TypeCode * type) throw (ConversionException)
1393 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1394 if(impl == CORBANode::IMPL_NAME)
1396 return adaptCppToCorba(source,type);
1398 else if(impl == PythonNode::IMPL_NAME)
1400 return adaptCppToPython(source,type);
1402 else if(impl == XmlNode::IMPL_NAME)
1404 return adaptCppToXml(source,type);
1406 else if(impl == CppNode::IMPL_NAME)
1408 return adaptCppToCpp(source, type);
1410 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1412 return adaptCppToNeutral(source, type);
1417 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1418 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1419 throw ConversionException(msg.str());
1423 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1424 // const InputPort* inputPort)
1426 // bool result=true;
1430 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1435 PyObject * RuntimeSALOME::getPyOrb()
1440 PyObject * RuntimeSALOME::getBuiltins()
1445 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1450 omniORBpyAPI* RuntimeSALOME::getApi()