1 // Copyright (C) 2006-2015 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #define private public
24 #define protected public
25 #include <omniORB4/CORBA.h>
26 #include <omniORB4/internal/typecode.h>
27 #include <omniORB4/internal/corbaOrb.h>
30 #include "yacsconfig.h"
31 #include "YACS_version.h"
32 #include "RuntimeSALOME.hxx"
33 #include "SALOMEDispatcher.hxx"
35 #include "TypeCode.hxx"
36 #include "WhileLoop.hxx"
37 #include "ForLoop.hxx"
38 #include "ForEachLoop.hxx"
39 #include "SalomeOptimizerLoop.hxx"
41 #include "InputPort.hxx"
42 #include "OutputPort.hxx"
43 #include "PresetPorts.hxx"
44 #include "InputDataStreamPort.hxx"
45 #include "OutputDataStreamPort.hxx"
46 #include "SalomeProc.hxx"
47 #include "PyStdout.hxx"
49 #include "SessionCataLoader.hxx"
52 #include "CORBAComponent.hxx"
53 #include "SalomeComponent.hxx"
54 #include "SalomeHPComponent.hxx"
55 #include "SalomePythonComponent.hxx"
56 #include "CppComponent.hxx"
58 #include "SalomeContainer.hxx"
59 #include "CppContainer.hxx"
60 #include "SalomeHPContainer.hxx"
63 #include "PythonNode.hxx"
64 #include "CORBANode.hxx"
65 #include "XMLNode.hxx"
66 #include "CppNode.hxx"
67 #include "PresetNode.hxx"
68 #include "OutNode.hxx"
69 #include "StudyNodes.hxx"
70 #include "SalomePythonNode.hxx"
71 #include "DistributedPythonNode.hxx"
74 #include "CORBACORBAConv.hxx"
75 #include "CORBAPythonConv.hxx"
76 #include "CORBAXMLConv.hxx"
77 #include "CORBACppConv.hxx"
78 #include "CORBANeutralConv.hxx"
80 #include "TypeConversions.hxx"
82 #include "PythonCORBAConv.hxx"
83 #include "PythonXMLConv.hxx"
84 #include "PythonCppConv.hxx"
85 #include "PythonNeutralConv.hxx"
86 #include "PythonInitConv.hxx"
89 #include "NeutralCORBAConv.hxx"
90 #include "NeutralPythonConv.hxx"
91 #include "NeutralXMLConv.hxx"
92 #include "NeutralCppConv.hxx"
93 #include "NeutralInitConv.hxx"
96 #include "CppCORBAConv.hxx"
97 #include "CppPythonConv.hxx"
98 #include "CppXMLConv.hxx"
99 #include "CppCppConv.hxx"
100 #include "CppNeutralConv.hxx"
103 #include "XMLCORBAConv.hxx"
104 #include "XMLPythonConv.hxx"
105 #include "XMLCppConv.hxx"
106 #include "XMLNeutralConv.hxx"
108 //Calcium specific ports
109 #include "CalStreamPort.hxx"
112 #include "SALOME_NamingService.hxx"
113 #include "SALOME_LifeCycleCORBA.hxx"
116 #include <libxml/parser.h>
117 #include <omniORB4/CORBA.h>
123 #include "YacsTrace.hxx"
126 using namespace YACS::ENGINE;
128 void RuntimeSALOME::setRuntime(long flags, int argc, char* argv[]) // singleton creation (not thread safe!)
130 if (! Runtime::_singleton)
132 RuntimeSALOME* r=new RuntimeSALOME(flags, argc, argv);
133 Runtime::_singleton = r;
136 DEBTRACE("RuntimeSALOME::setRuntime() done !");
139 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
141 YASSERT(Runtime::_singleton);
142 return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
146 * Singleton creation, initialize converter map
149 RuntimeSALOME::RuntimeSALOME()
154 void RuntimeSALOME::initBuiltins()
156 //Fill the builtin catalog with nodes specific to the runtime
157 std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
158 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
159 std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
160 std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
161 nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
162 nodeMap["PyScript"]=new PythonNode("PyScript");
163 nodeMap["CORBANode"]=new CORBANode("CORBANode");
164 nodeMap["XmlNode"]=new XmlNode("XmlNode");
165 nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
166 nodeMap["CppNode"]=new CppNode("CppNode");
167 nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
168 nodeMap["PresetNode"]=new PresetNode("PresetNode");
169 nodeMap["OutNode"]=new OutNode("OutNode");
170 nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
171 nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
172 composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
173 typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
174 typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
175 typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
176 typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
177 typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
178 typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
179 typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
180 typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
181 std::list<TypeCodeObjref *> ltc;
182 typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
183 typeMap["seqpyobj"]= createSequenceTc("seqpyobj","seqpyobj",typeMap["pyobj"]);
184 composednodeMap["ForEachLoop_pyobj"]=createForEachLoop("ForEachLoop_pyobj",typeMap["pyobj"]);;
185 ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
186 t->addMember("ref",_tc_string);
187 typeMap["dataref"]= t;
190 RuntimeSALOME::RuntimeSALOME(long flags, int argc, char* argv[])
192 // If all flags (apart the IsPyExt flags) are unset, force them to true
193 if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
194 flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
195 + RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
197 // Salome Nodes implies Corba Nodes
198 if (flags & RuntimeSALOME::UseSalome)
199 flags |= RuntimeSALOME::UseCorba;
201 // Corba Nodes implies Python Nodes
202 if (flags & RuntimeSALOME::UseCorba)
203 flags |= RuntimeSALOME::UsePython;
205 _useCorba = flags & RuntimeSALOME::UseCorba;
206 _usePython = flags & RuntimeSALOME::UsePython;
207 _useCpp = flags & RuntimeSALOME::UseCpp;
208 _useXml = flags & RuntimeSALOME::UseXml;
213 if (_useCpp) _setOfImplementation.insert(CppNode::IMPL_NAME);
214 if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
215 if (_useCorba) _setOfImplementation.insert(CORBANode::IMPL_NAME);
216 if (_useXml) _setOfImplementation.insert(XmlNode::IMPL_NAME);
217 init(flags, argc, argv);
220 RuntimeSALOME::~RuntimeSALOME()
222 DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
223 // destroy catalog loader prototypes
224 std::map<std::string, CatalogLoader*>::const_iterator pt;
225 for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
231 //! CORBA and Python initialization
233 * \param flags contains several bits
234 * bit0 (ispyext) true when method is called from Python
235 * (Python initialization must not be done!)
236 * bit1 (UsePython) true if python nodes are needed
237 * bit1 (UseCorba) true if CORBA nodes are needed
238 * bit1 (UseXml) true if python nodes are needed
239 * bit1 (UseCpp) true if C++ nodes are needed
240 * bit1 (UseSalome) true if Salome nodes are needed
241 * \param argc number of command line arguments (used to initialize the Python interpreter)
242 * \param argv command line arguments (used to initialize the Python interpreter)
246 void RuntimeSALOME::init(long flags, int argc, char* argv[])
248 bool ispyext = flags & RuntimeSALOME::IsPyExt;
251 PortableServer::POA_var root_poa;
252 PortableServer::POAManager_var pman;
253 CORBA::Object_var obj;
254 int nbargs = 0; char **args = 0;
255 _orb = CORBA::ORB_init (nbargs, args);
256 obj = _orb->resolve_initial_references("RootPOA");
257 root_poa = PortableServer::POA::_narrow(obj);
258 pman = root_poa->the_POAManager();
262 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
264 obj = _orb->resolve_initial_references("DynAnyFactory");
265 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
270 DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
272 // Initialize Python interpreter in embedded mode
273 if (!Py_IsInitialized())
275 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
278 Py_InitializeEx(0); // do not install signal handlers
280 if (argc > 0 && argv != NULL)
281 PySys_SetArgv(argc, argv);
286 char defaultName[] = "SALOME_YACS_RUNTIME";
287 pyArgv[0] = defaultName;
288 PySys_SetArgv(pyArgc, pyArgv);
290 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
291 PyEval_SaveThread(); /* Release the thread state */
292 //here we do not have the Global Interpreter Lock
295 PyObject *mainmod,*pyapi,*res ;
297 PyGILState_STATE gstate;
298 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
300 mainmod = PyImport_AddModule("__main__");
301 globals = PyModule_GetDict(mainmod);
302 /* globals is a borrowed reference */
304 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
306 PyObject *bimod = PyImport_ImportModule("__builtin__");
307 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
308 Py_FatalError("can't add __builtins__ to __main__");
312 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
318 _omnipy = PyImport_ImportModule((char*)"_omnipy");
322 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
325 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
330 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
333 res=PyRun_String("\n"
334 "from math import *\n"
336 "sys.path.insert(0,'.')\n"
337 "from omniORB import CORBA\n"
338 "from omniORB import any\n"
339 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
340 "#print sys.getrefcount(orb)\n"
346 Py_file_input,globals,globals );
354 _pyorb = PyDict_GetItemString(globals,"orb");
355 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
358 pyany = PyDict_GetItemString(globals,"any");
359 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
362 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
366 PyGILState_Release(gstate); // Release the Global Interpreter Lock
370 // initialize the catalogLoaderFactory map with the session one
371 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
375 void RuntimeSALOME::fini()
379 PyGILState_STATE gstate = PyGILState_Ensure();
381 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
383 PyObject *mainmod, *globals;
384 mainmod = PyImport_AddModule("__main__");
385 globals = PyModule_GetDict(mainmod);
389 res=PyRun_String("orb.destroy()\n"
391 Py_file_input,globals,globals );
397 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
398 delete nodeMap["PyFunction"];
399 delete nodeMap["PyScript"];
400 delete nodeMap["SalomePythonNode"];
401 nodeMap.erase("PyFunction");
402 nodeMap.erase("PyScript");
403 nodeMap.erase("SalomePythonNode");
407 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
415 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
422 std::string RuntimeSALOME::getVersion() const
424 #ifdef YACS_DEVELOPMENT
425 return CORBA::string_dup(YACS_VERSION_STR"dev");
427 return CORBA::string_dup(YACS_VERSION_STR);
431 Proc* RuntimeSALOME::createProc(const std::string& name)
433 return new SalomeProc(name);
436 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
437 std::list<TypeCodeObjref *> ltc)
440 if(id == "") myName = "IDL:" + name + ":1.0";
442 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
445 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
446 const std::string& name,
449 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
452 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
455 if(id == "") myName = "IDL:" + name + ":1.0";
457 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
460 Bloc* RuntimeSALOME::createBloc(const std::string& name)
462 return new Bloc(name);
465 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
467 return new WhileLoop(name);
470 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
472 return new ForLoop(name);
475 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
476 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
478 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
479 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
480 ol->edGetNbOfBranchesPort()->edInit(1);
484 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
489 node = new PresetNode(name);
492 else if(kind == "study" )
494 return new StudyInNode(name);
496 std::string msg="DataNode kind ("+kind+") unknown";
497 throw Exception(msg);
500 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
504 return new OutNode(name);
506 else if(kind == "study" )
508 return new StudyOutNode(name);
511 std::string msg="OutDataNode kind ("+kind+") unknown";
512 throw Exception(msg);
515 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
517 InlineFuncNode* node;
518 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
520 node = new PyFuncNode(name);
523 if(kind == DistributedPythonNode::KIND)
524 return new DistributedPythonNode(name);
525 std::string msg="FuncNode kind ("+kind+") unknown";
526 throw Exception(msg);
529 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
532 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
534 node = new PythonNode(name);
537 std::string msg="ScriptNode kind ("+kind+") unknown";
538 throw Exception(msg);
541 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
544 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
546 node = new CORBANode(name);
549 else if(kind == XmlNode::KIND)
551 node = new XmlNode(name);
554 std::string msg="RefNode kind ("+kind+") unknown";
555 throw Exception(msg);
558 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
561 if(kind == "" || kind == SalomeNode::KIND )
563 node=new SalomeNode(name);
566 else if (kind == CppNode::KIND)
568 node = new CppNode(name);
571 std::string msg="CompoNode kind ("+kind+") unknown";
572 throw Exception(msg);
575 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
577 if(kind == "" || kind == SalomeNode::KIND )
578 return new SalomePythonNode(name);
579 std::string msg="CompoNode kind ("+kind+") unknown";
580 throw Exception(msg);
583 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
584 const std::string& kind)
586 ComponentInstance* compo;
587 if(kind == "" || kind == SalomeComponent::KIND)
588 return new SalomeComponent(name);
589 else if(kind == CORBAComponent::KIND)
590 return new CORBAComponent(name);
591 else if(kind == SalomePythonComponent::KIND)
592 return new SalomePythonComponent(name);
593 else if (kind == CppComponent::KIND)
594 return new CppComponent(name);
595 else if (kind == SalomeHPComponent::KIND)
596 return new SalomeHPComponent(name);
597 std::string msg="Component Instance kind ("+kind+") unknown";
598 throw Exception(msg);
601 Container *RuntimeSALOME::createContainer(const std::string& kind)
603 if(kind == "" || kind == SalomeContainer::KIND)
604 return new SalomeContainer;
605 if(kind==SalomeHPContainer::KIND)
606 return new SalomeHPContainer;
607 else if (kind == CppContainer::KIND)
608 return new CppContainer;
609 std::string msg="Container kind ("+kind+") unknown";
610 throw Exception(msg);
613 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
614 const std::string& impl,
618 if(impl == CppNode::IMPL_NAME)
620 return new InputCppPort(name, node, type);
622 else if(impl == PythonNode::IMPL_NAME)
624 return new InputPyPort(name, node, type);
626 else if(impl == CORBANode::IMPL_NAME)
628 return new InputCorbaPort(name, node, type);
630 else if(impl == XmlNode::IMPL_NAME)
632 return new InputXmlPort(name, node, type);
637 msg << "Cannot create " << impl << " InputPort" ;
638 msg << " ("__FILE__ << ":" << __LINE__ << ")";
639 throw Exception(msg.str());
643 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
644 const std::string& impl,
648 if(impl == CppNode::IMPL_NAME)
650 return new OutputCppPort(name, node, type);
652 else if(impl == PythonNode::IMPL_NAME)
654 return new OutputPyPort(name, node, type);
656 else if(impl == CORBANode::IMPL_NAME)
658 return new OutputCorbaPort(name, node, type);
660 else if(impl == XmlNode::IMPL_NAME)
662 return new OutputXmlPort(name, node, type);
667 msg << "Cannot create " << impl << " OutputPort" ;
668 msg << " ("__FILE__ << ":" << __LINE__ << ")";
669 throw Exception(msg.str());
673 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
674 Node *node,TypeCode *type)
676 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
677 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
679 return new InputCalStreamPort(name,node,type);
683 return new InputDataStreamPort(name,node,type);
687 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
688 Node *node,TypeCode *type)
690 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
691 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
693 return new OutputCalStreamPort(name,node,type);
697 return new OutputDataStreamPort(name,node,type);
701 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
703 * \param source : InputPort to be adapted
704 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
705 * \param type : data type provided by the InputPort
706 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
708 * \return : adapted InputPort
710 InputPort* RuntimeSALOME::adapt(InputPort* source,
711 const std::string& impl,
712 TypeCode * type,bool init) throw (ConversionException)
714 string imp_source=source->getNode()->getImplementation();
715 if(imp_source == PythonNode::IMPL_NAME)
717 return adapt((InputPyPort*)source,impl,type,init);
719 else if(imp_source == CppNode::IMPL_NAME)
721 return adapt((InputCppPort*)source,impl,type,init);
723 else if(imp_source == CORBANode::IMPL_NAME)
725 return adapt((InputCorbaPort*)source,impl,type,init);
727 else if(imp_source == XmlNode::IMPL_NAME)
729 return adapt((InputXmlPort*)source,impl,type,init);
731 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
733 return adaptNeutral(source,impl,type,init);
738 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
739 msg << " ("__FILE__ << ":" << __LINE__ << ")";
740 throw ConversionException(msg.str());
744 //! Adapter function for InPropertyPort
746 * \param source : InPropertyPort to be adapted
747 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
748 * \param type : data type provided by the InPropertyPort
749 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
751 * \return : adapted InputPort
753 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
754 const std::string& impl,
755 TypeCode * type,bool init) throw (ConversionException)
757 return adaptNeutral((InputPort *)source,impl,type,init);
760 //! Adapt a Neutral input port to a Corba output port
762 * \param inport : Neutral input port to adapt to Corba type type
763 * \param type : output port type
764 * \return an adaptated input port of type InputCorbaPort
766 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
767 TypeCode * type) throw (ConversionException)
769 // BEWARE : using the generic check
770 if(inport->edGetType()->isAdaptable(type))
772 //the output data is convertible to inport type
773 return new CorbaNeutral(inport);
775 //non convertible type
777 msg << "Cannot connect Corba output port with type: " << type->id() ;
778 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
780 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
782 throw ConversionException(msg.str());
785 //! Adapt a Neutral input port to a Python output port
787 * \param inport : input port to adapt to Python type type
788 * \param type : output port type
789 * \return an adaptated input port of type InputPyPort
791 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
792 TypeCode * type) throw (ConversionException)
794 // BEWARE : using the generic check
795 if(inport->edGetType()->isAdaptable(type))
798 return new PyNeutral(inport);
800 //non convertible type
802 msg << "Cannot connect Python output port with type: " << type->id() ;
803 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
805 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
807 throw ConversionException(msg.str());
810 //! Adapt a Neutral input port to a Xml output port
812 * \param inport : input port to adapt to Xml type type
813 * \param type : output port type
814 * \return an input port of type InputXmlPort
816 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
817 TypeCode * type) throw (ConversionException)
819 // BEWARE : using the generic check
820 if(inport->edGetType()->isAdaptable(type))
823 return new XmlNeutral(inport);
825 //non convertible type
827 msg << "Cannot connect Xml output port with type: " << type->id() ;
828 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
830 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
832 throw ConversionException(msg.str());
835 //! Adapt a Neutral input port to a C++ output port
837 * \param inport : input port to adapt to C++ type type
838 * \param type : output port type
839 * \return an input port of type InputCppPort
841 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
842 TypeCode * type) throw (ConversionException)
844 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
845 if(isAdaptableNeutralCpp(type,inport->edGetType()))
848 return new CppNeutral(inport);
850 //non convertible type
852 msg << "Cannot connect Cpp output port with type: " << type->id() ;
853 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
855 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
857 throw ConversionException(msg.str());
860 //! Adapt a Neutral input port to connect it to an output port with a given implementation
862 * \param source : Neutral input port to adapt to implementation impl and type type
863 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
864 * \param type : output port supported type
865 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
866 * \return the adaptated port
868 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
869 const std::string& impl,
870 TypeCode * type,bool init) throw (ConversionException)
872 if(impl == CppNode::IMPL_NAME)
874 return adaptNeutralToCpp(source,type);
876 else if(impl == PythonNode::IMPL_NAME)
878 return adaptNeutralToPython(source,type);
880 else if(impl == CORBANode::IMPL_NAME)
882 return adaptNeutralToCorba(source,type);
884 else if(impl == XmlNode::IMPL_NAME )
886 return adaptNeutralToXml(source,type);
888 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
891 return new NeutralInit(source);
893 return new ProxyPort(source);
896 msg << "Cannot connect InputPort : unknown implementation " << impl;
897 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
898 throw ConversionException(msg.str());
901 //! Adapt a XML input port to connect it to a CORBA output port
903 * \param inport : input port to adapt to CORBA type type
904 * \param type : type supported by output port
905 * \return an adaptator port of type InputCorbaPort
908 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
909 TypeCode * type) throw (ConversionException)
911 if(isAdaptableXmlCorba(type,inport->edGetType()))
913 //output type is convertible to input type
914 return new CorbaXml(inport);
916 //output type is not convertible
918 msg << "Cannot connect Corba output port with type: " << type->id() ;
919 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
921 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
923 throw ConversionException(msg.str());
926 //! Adapt a XML input port to a Python output port
928 * \param inport : input port to adapt to Python type type
929 * \param type : output port type
930 * \return an adaptated input port of type InputPyPort
932 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
933 TypeCode * type) throw (ConversionException)
935 if(inport->edGetType()->isAdaptable(type))
937 //the output data is convertible to inport type
938 return new PyXml(inport);
940 //non convertible type
942 msg << "Cannot connect Python output port with type: " << type->id() ;
943 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
945 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
947 throw ConversionException(msg.str());
950 //! Adapt a XML input port to a C++ output port
952 * \param inport : input port to adapt to C++ type type
953 * \param type : output port type
954 * \return an adaptated input port of type InputPyPort
956 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
957 TypeCode * type) throw (ConversionException)
959 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
960 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
961 if(type->isAdaptable(inport->edGetType()))
963 //the output data is convertible to inport type
964 return new CppXml(inport);
966 //non convertible type
968 msg << "Cannot connect Cpp output port with type: " << type->id() ;
969 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
971 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
973 throw ConversionException(msg.str());
976 //! Adapt a XML input port to a Neutral output port
978 * \param inport : input port to adapt to Neutral type type
979 * \param type : output port type
980 * \return an adaptated input port of type Neutralxxxx
982 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
983 TypeCode * type) throw (ConversionException)
985 if(inport->edGetType()->isAdaptable(type))
987 //the output data is convertible to inport type
988 return new NeutralXml(inport);
990 //non convertible type
992 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
993 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
994 throw ConversionException(msg.str());
997 //! Adapt a XML input port to a Xml output port
999 * \param inport : input port to adapt to Xml type type
1000 * \param type : output port type
1001 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1002 * \return an adaptated input port of type Xmlxxxx
1004 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
1005 TypeCode * type,bool init) throw (ConversionException)
1008 return new ProxyPort(inport);
1010 if(inport->edGetType()->isAdaptable(type))
1011 return new ProxyPort(inport);
1014 msg << "Cannot connect Xml output port with type: " << type->id() ;
1015 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1017 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1019 throw ConversionException(msg.str());
1022 //! Adapt an Xml input port to an output port which implementation is given by impl
1024 * \param source : input port to adapt to implementation impl and type type
1025 * \param impl : output port implementation (C++, Python or Corba)
1026 * \param type : output port supported type
1027 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1028 * \return the adaptated port
1031 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1032 const std::string& impl,
1033 TypeCode * type,bool init) throw (ConversionException)
1035 if(impl == CORBANode::IMPL_NAME)
1037 return adaptXmlToCorba(source,type);
1039 else if(impl == PythonNode::IMPL_NAME)
1041 return adaptXmlToPython(source,type);
1043 else if(impl == CppNode::IMPL_NAME)
1045 return adaptXmlToCpp(source,type);
1047 else if(impl == XmlNode::IMPL_NAME )
1049 return adaptXmlToXml(source,type,init);
1051 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1053 return adaptXmlToNeutral(source,type);
1058 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1059 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1060 throw ConversionException(msg.str());
1065 //! Adapt a CORBA input port to a CORBA output port
1067 * \param inport : input port to adapt to CORBA outport data type
1068 * \param type : outport data type
1069 * \return an adaptator port of type InputCORBAPort
1071 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1072 TypeCode * type) throw (ConversionException)
1074 if(type->isA(inport->edGetType()))
1076 //types are compatible : no conversion
1077 //outport data type is more specific than inport required type
1078 //so the inport can be used safely
1079 return new ProxyPort(inport);
1081 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1083 //ouport data can be converted to inport data type
1084 return new CorbaCorba(inport);
1086 //outport data can not be converted
1088 msg << "Cannot connect Corba output port with type: " << type->id() ;
1089 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1091 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1093 throw ConversionException(msg.str());
1096 //! Adapt a CORBA input port to a Python output port
1098 * \param inport : input port to adapt to Python type type
1099 * \param type : outport data type
1100 * \return an adaptator port of type InputPyPort
1103 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1104 TypeCode * type) throw (ConversionException)
1106 if(inport->edGetType()->kind() == Double)
1108 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1110 else if(inport->edGetType()->kind() == Int)
1112 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1114 else if(inport->edGetType()->kind() == String)
1116 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1118 else if(inport->edGetType()->kind() == Bool)
1120 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1122 else if(inport->edGetType()->kind() == Objref )
1124 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1126 return new PyCorbaObjref(inport);
1131 msg << "Cannot connect Python output port with type: " << type->id() ;
1132 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1133 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1134 throw ConversionException(msg.str());
1137 else if(inport->edGetType()->kind() == Sequence)
1139 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1141 return new PyCorbaSequence(inport);
1146 msg << "Cannot convert this sequence type " ;
1147 msg << __FILE__ << ":" <<__LINE__;
1148 throw ConversionException(msg.str());
1151 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1153 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1155 return new PyCorbaStruct(inport);
1160 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1161 msg << __FILE__ << ":" <<__LINE__;
1162 throw ConversionException(msg.str());
1165 // Adaptation not possible
1167 msg << "Cannot connect Python output port with type: " << type->id() ;
1168 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1170 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1172 throw ConversionException(msg.str());
1175 //! Adapt a CORBA input port to connect it to a XML output port
1177 * \param inport : input port to adapt to Xml type type
1178 * \param type : type supported by output port
1179 * \return an adaptator port of type InputXmlPort
1182 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1183 TypeCode * type) throw (ConversionException)
1185 // BEWARE : using the generic check
1186 if(inport->edGetType()->isAdaptable(type))
1188 //output type is convertible to input type
1189 return new XmlCorba(inport);
1191 //output type is not convertible
1193 msg << "Cannot connect Xml output port with type: " << type->id() ;
1194 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1196 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1198 throw ConversionException(msg.str());
1201 //! Adapt a CORBA input port to a C++ output port
1203 * \param inport : input port to adapt to C++ type type
1204 * \param type : outport data type
1205 * \return an adaptator port of type InputCPPPort
1208 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1209 TypeCode * type) throw (ConversionException)
1211 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1212 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1214 //output type is convertible to input type
1215 return new CppCorba(inport);
1217 //output type is not convertible
1219 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1220 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1222 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1224 throw ConversionException(msg.str());
1227 //! Adapt a CORBA input port to a neutral data
1229 * \param inport : InputPort to adapt to Neutral type type
1230 * \param type : outport data type
1231 * \return an adaptator port of type Neutralxxxx
1234 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1235 TypeCode * type) throw (ConversionException)
1237 if(inport->edGetType()->kind() == Double)
1239 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1241 else if(inport->edGetType()->kind() == Int)
1243 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1245 else if(inport->edGetType()->kind() == String)
1247 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1249 else if(inport->edGetType()->kind() == Bool)
1251 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1253 else if(inport->edGetType()->kind() == Objref)
1255 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1257 else if(inport->edGetType()->kind() == Sequence)
1259 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1260 return new NeutralCorbaSequence(inport);
1264 msg << "Cannot convert this sequence type " ;
1265 msg << __FILE__ << ":" <<__LINE__;
1266 throw ConversionException(msg.str());
1269 else if(inport->edGetType()->kind() == Struct)
1271 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1274 // Adaptation not possible
1276 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1277 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1279 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1281 throw ConversionException(msg.str());
1284 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1286 * \param source : input port to adapt to implementation impl and type type
1287 * \param impl : output port implementation (C++, Python or Corba)
1288 * \param type : outport data type
1289 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1290 * \return an adaptator port which type depends on impl
1293 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1294 const std::string& impl,
1295 TypeCode * type,bool init) throw (ConversionException)
1297 if(impl == CppNode::IMPL_NAME)
1299 return adaptCorbaToCpp(source,type);
1301 else if(impl == PythonNode::IMPL_NAME)
1303 return adaptCorbaToPython(source,type);
1305 else if(impl == CORBANode::IMPL_NAME)
1308 return adaptCorbaToCorba(source,type);
1310 return adaptCorbaToCorba(source,type);
1312 else if(impl == XmlNode::IMPL_NAME )
1314 return adaptCorbaToXml(source,type);
1316 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1318 return adaptCorbaToNeutral(source,type);
1323 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1324 msg << __FILE__ << ":" <<__LINE__;
1325 throw ConversionException(msg.str());
1329 //! Adapt a Python input port to a Python output port
1331 * No need to make conversion or cast.
1332 * Only check, it's possible.
1333 * \param inport : InputPort to adapt to Python type type
1334 * \param type : outport data type
1335 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1336 * \return an adaptator port of type InputPyPort
1339 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1340 TypeCode * type,bool init) throw (ConversionException)
1343 return new PyInit(inport);
1345 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1347 //output data is convertible to input type
1348 //With python, no need to convert. Conversion will be done automatically
1349 //by the interpreter
1350 return new ProxyPort(inport);
1352 //output data is not convertible to input type
1354 msg << "Cannot connect Python output port with type: " << type->id() ;
1355 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1357 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1359 throw ConversionException(msg.str());
1362 //! Adapt a Python input port to a C++ output port
1364 * \param inport : InputPort to adapt to C++ type type
1365 * \param type : outport data type
1366 * \return an adaptator port of C++ type (InputCppPort)
1369 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1370 TypeCode * type) throw (ConversionException)
1372 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1373 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1375 //output type is convertible to input type
1376 return new CppPy(inport);
1378 //output type is not convertible
1380 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1381 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1383 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1385 throw ConversionException(msg.str());
1388 //! Adapt a Python input port to a Neutral data port
1390 * \param inport : InputPort to adapt to Neutral type type
1391 * \param type : outport data type
1392 * \return an adaptator port of Neutral type (Neutralxxxx)
1395 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1396 TypeCode * type) throw (ConversionException)
1398 if(inport->edGetType()->kind() == Double)
1400 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1402 else if(inport->edGetType()->kind() == Int)
1404 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1406 else if(inport->edGetType()->kind() == String)
1408 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1410 else if(inport->edGetType()->kind() == Bool)
1412 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1414 else if(inport->edGetType()->kind() == Objref)
1416 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1418 else if(inport->edGetType()->kind() == Sequence)
1420 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1421 return new NeutralPySequence(inport);
1425 msg << "Cannot convert this sequence type " ;
1426 msg << __FILE__ << ":" <<__LINE__;
1427 throw ConversionException(msg.str());
1430 else if(inport->edGetType()->kind() == Struct)
1432 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1435 // Adaptation not possible
1437 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1438 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1440 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1442 throw ConversionException(msg.str());
1445 //! Adapt a Python input port to a Corba output port
1447 * Always convert the data
1448 * \param inport : InputPort to adapt to Corba type type
1449 * \param type : outport data type
1450 * \return an adaptator port of Corba type (InputCorbaPort)
1453 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1454 TypeCode * type) throw (ConversionException)
1456 if(inport->edGetType()->kind() == Double)
1458 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1460 else if(inport->edGetType()->kind() == Int)
1462 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1464 else if(inport->edGetType()->kind() == String)
1466 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1468 else if(inport->edGetType()->kind() == Bool)
1470 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1472 else if(inport->edGetType()->kind() == Objref)
1474 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1476 return new CorbaPyObjref(inport);
1481 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1482 msg << " " << __FILE__ << ":" <<__LINE__;
1483 throw ConversionException(msg.str());
1486 else if(inport->edGetType()->kind() == Sequence)
1488 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1490 return new CorbaPySequence(inport);
1495 msg << "Cannot convert this sequence type " ;
1496 msg << __FILE__ << ":" <<__LINE__;
1497 throw ConversionException(msg.str());
1500 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1502 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1504 return new CorbaPyStruct(inport);
1509 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1510 msg << " " << __FILE__ << ":" <<__LINE__;
1511 throw ConversionException(msg.str());
1514 // Adaptation not possible
1516 msg << "Cannot connect Corba output port with type: " << type->id() ;
1517 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1519 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1521 throw ConversionException(msg.str());
1524 //! Adapt a Python input port to a Xml output port
1526 * \param inport : input port to adapt to Xml type type
1527 * \param type : output port type
1528 * \return an input port of type InputXmlPort
1531 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1532 TypeCode * type) throw (ConversionException)
1534 // BEWARE : using the generic check
1535 if(inport->edGetType()->isAdaptable(type))
1538 return new XmlPython(inport);
1540 //non convertible type
1542 msg << "Cannot connect Xml output port with type: " << type->id() ;
1543 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1545 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1547 throw ConversionException(msg.str());
1550 //! Adapt a Python input port to an output port with a given implementation
1552 * \param source : input port to adapt to implementation impl and type type
1553 * \param impl : output port implementation (C++, Python or Corba)
1554 * \param type : output port type
1555 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1556 * \return adaptated input port
1559 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1560 const std::string& impl,
1561 TypeCode * type,bool init) throw (ConversionException)
1563 if(impl == CppNode::IMPL_NAME)
1565 return adaptPythonToCpp(source,type);
1567 else if(impl == PythonNode::IMPL_NAME)
1569 return adaptPythonToPython(source,type,init);
1571 else if(impl == CORBANode::IMPL_NAME)
1573 return adaptPythonToCorba(source,type);
1575 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1577 return adaptPythonToNeutral(source,type);
1579 else if(impl == XmlNode::IMPL_NAME)
1581 return adaptPythonToXml(source,type);
1586 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1587 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1588 throw ConversionException(msg.str());
1593 //! Adapt a C++ input port to connect it to a CORBA output port
1595 * \param inport : input port to adapt to CORBA type type
1596 * \param type : type supported by output port
1597 * \return an adaptator port of type InputCorbaPort
1600 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1601 TypeCode * type) throw (ConversionException)
1603 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1604 if(isAdaptableCppCorba(type,inport->edGetType()))
1606 //output type is convertible to input type
1607 return new CorbaCpp(inport);
1609 //output type is not convertible
1611 msg << "Cannot connect Corba output port with type: " << type->id() ;
1612 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1614 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1616 throw ConversionException(msg.str());
1619 //! Adapt a C++ input port to a Python output port
1621 * \param inport : input port to adapt to Python type type
1622 * \param type : output port type
1623 * \return an adaptated input port of type InputPyPort
1625 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1626 TypeCode * type) throw (ConversionException)
1628 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1629 if(isAdaptableCppPyObject(type,inport->edGetType()))
1631 //output type is convertible to input type
1632 return new PyCpp(inport);
1634 //output type is not convertible
1636 msg << "Cannot connect Python output port with type: " << type->id() ;
1637 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1639 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1641 throw ConversionException(msg.str());
1644 //! Adapt a C++ input port to a C++ output port
1646 * \param inport : input port to adapt to C++ type type
1647 * \param type : output port type
1648 * \return an adaptated input port of type InputPyPort
1650 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1651 TypeCode * type) throw (ConversionException)
1653 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1654 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1655 if(type->isAdaptable(inport->edGetType()))
1657 //the output data is convertible to inport type
1658 return new CppCpp(inport);
1660 //non convertible type
1662 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1663 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1665 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1667 throw ConversionException(msg.str());
1670 //! Adapt a C++ input port to a Neutral output port
1672 * \param inport : input port to adapt to C++ type type
1673 * \param type : output port type
1674 * \return an adaptated input port of type InputPyPort
1676 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1677 TypeCode * type) throw (ConversionException)
1679 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1680 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1681 if(type->isAdaptable(inport->edGetType()))
1683 //the output data is convertible to inport type
1684 return new NeutralCpp(inport);
1686 //non convertible type
1688 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1689 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1691 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1693 throw ConversionException(msg.str());
1696 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1697 TypeCode * type) throw (ConversionException)
1699 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1700 if(isAdaptableCppXml(type,inport->edGetType()))
1703 return new XmlCpp(inport);
1705 //non convertible type
1707 msg << "Cannot connect Xml output port with type: " << type->id() ;
1708 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1710 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1712 throw ConversionException(msg.str());
1715 //! Adapt a C++ input port to connect it to an output port with a given implementation
1717 * \param source : input port to adapt to implementation impl and type type
1718 * \param impl : output port implementation (C++, Python or Corba)
1719 * \param type : output port supported type
1720 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1721 * \return the adaptated port
1724 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1725 const std::string& impl,
1726 TypeCode * type,bool init) throw (ConversionException)
1728 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1729 if(impl == CORBANode::IMPL_NAME)
1731 return adaptCppToCorba(source,type);
1733 else if(impl == PythonNode::IMPL_NAME)
1735 return adaptCppToPython(source,type);
1737 else if(impl == XmlNode::IMPL_NAME)
1739 return adaptCppToXml(source,type);
1741 else if(impl == CppNode::IMPL_NAME)
1743 return adaptCppToCpp(source, type);
1745 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1747 return adaptCppToNeutral(source, type);
1752 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1753 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1754 throw ConversionException(msg.str());
1758 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1759 // const InputPort* inputPort)
1761 // bool result=true;
1765 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1770 PyObject * RuntimeSALOME::getPyOrb()
1775 PyObject * RuntimeSALOME::getBuiltins()
1780 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1785 PyObject * RuntimeSALOME::get_omnipy()
1790 omniORBpyAPI* RuntimeSALOME::getApi()
1795 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1798 return (void *)convertNeutralPyObject(type,data);
1802 return (void *)Py_None;
1806 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1811 ob=convertNeutralPyObject(type,data);
1812 std::string s=convertPyObjectToString(ob);
1814 // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1815 // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1816 // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1817 // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1818 // feel free to change this code.
1819 PyGILState_STATE gstate = PyGILState_Ensure();
1821 PyGILState_Release(gstate);
1830 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1832 return YACS::ENGINE::convertPyObjectToString(ob);
1835 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1840 PyGILState_STATE gstate = PyGILState_Ensure();
1841 mainmod = PyImport_AddModule("__main__");
1842 globals = PyModule_GetDict(mainmod);
1843 PyObject* d = PyDict_New();
1844 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1845 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1851 PyObject* new_stderr = newPyStdOut(error);
1852 PySys_SetObject((char *)"stderr", new_stderr);
1854 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1855 Py_DECREF(new_stderr);
1856 PyGILState_Release(gstate);
1857 throw Exception(error);
1859 PyGILState_Release(gstate);