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 "SalomeOptimizerLoop.hxx"
40 #include "InputPort.hxx"
41 #include "OutputPort.hxx"
42 #include "PresetPorts.hxx"
43 #include "InputDataStreamPort.hxx"
44 #include "OutputDataStreamPort.hxx"
45 #include "SalomeProc.hxx"
46 #include "PyStdout.hxx"
48 #include "SessionCataLoader.hxx"
51 #include "CORBAComponent.hxx"
52 #include "SalomeComponent.hxx"
53 #include "SalomeHPComponent.hxx"
54 #include "SalomePythonComponent.hxx"
55 #include "CppComponent.hxx"
57 #include "SalomeContainer.hxx"
58 #include "CppContainer.hxx"
59 #include "SalomeHPContainer.hxx"
62 #include "PythonNode.hxx"
63 #include "CORBANode.hxx"
64 #include "XMLNode.hxx"
65 #include "CppNode.hxx"
66 #include "PresetNode.hxx"
67 #include "OutNode.hxx"
68 #include "StudyNodes.hxx"
69 #include "SalomePythonNode.hxx"
70 #include "DistributedPythonNode.hxx"
73 #include "CORBACORBAConv.hxx"
74 #include "CORBAPythonConv.hxx"
75 #include "CORBAXMLConv.hxx"
76 #include "CORBACppConv.hxx"
77 #include "CORBANeutralConv.hxx"
79 #include "TypeConversions.hxx"
81 #include "PythonCORBAConv.hxx"
82 #include "PythonXMLConv.hxx"
83 #include "PythonCppConv.hxx"
84 #include "PythonNeutralConv.hxx"
85 #include "PythonInitConv.hxx"
88 #include "NeutralCORBAConv.hxx"
89 #include "NeutralPythonConv.hxx"
90 #include "NeutralXMLConv.hxx"
91 #include "NeutralCppConv.hxx"
92 #include "NeutralInitConv.hxx"
95 #include "CppCORBAConv.hxx"
96 #include "CppPythonConv.hxx"
97 #include "CppXMLConv.hxx"
98 #include "CppCppConv.hxx"
99 #include "CppNeutralConv.hxx"
102 #include "XMLCORBAConv.hxx"
103 #include "XMLPythonConv.hxx"
104 #include "XMLCppConv.hxx"
105 #include "XMLNeutralConv.hxx"
107 //Calcium specific ports
108 #include "CalStreamPort.hxx"
111 #include "SALOME_NamingService.hxx"
112 #include "SALOME_LifeCycleCORBA.hxx"
115 #include <libxml/parser.h>
116 #include <omniORB4/CORBA.h>
122 #include "YacsTrace.hxx"
125 using namespace YACS::ENGINE;
127 void RuntimeSALOME::setRuntime(long flags, int argc, char* argv[]) // singleton creation (not thread safe!)
129 if (! Runtime::_singleton)
131 RuntimeSALOME* r=new RuntimeSALOME(flags, argc, argv);
132 Runtime::_singleton = r;
135 DEBTRACE("RuntimeSALOME::setRuntime() done !");
138 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
140 YASSERT(Runtime::_singleton);
141 return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
145 * Singleton creation, initialize converter map
148 RuntimeSALOME::RuntimeSALOME()
153 void RuntimeSALOME::initBuiltins()
155 //Fill the builtin catalog with nodes specific to the runtime
156 std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
157 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
158 std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
159 std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
160 nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
161 nodeMap["PyScript"]=new PythonNode("PyScript");
162 nodeMap["CORBANode"]=new CORBANode("CORBANode");
163 nodeMap["XmlNode"]=new XmlNode("XmlNode");
164 nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
165 nodeMap["CppNode"]=new CppNode("CppNode");
166 nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
167 nodeMap["PresetNode"]=new PresetNode("PresetNode");
168 nodeMap["OutNode"]=new OutNode("OutNode");
169 nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
170 nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
171 composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
172 typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
173 typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
174 typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
175 typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
176 typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
177 typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
178 typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
179 typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
180 std::list<TypeCodeObjref *> ltc;
181 typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
182 ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
183 t->addMember("ref",_tc_string);
184 typeMap["dataref"]= t;
187 RuntimeSALOME::RuntimeSALOME(long flags, int argc, char* argv[])
189 // If all flags (apart the IsPyExt flags) are unset, force them to true
190 if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
191 flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
192 + RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
194 // Salome Nodes implies Corba Nodes
195 if (flags & RuntimeSALOME::UseSalome)
196 flags |= RuntimeSALOME::UseCorba;
198 // Corba Nodes implies Python Nodes
199 if (flags & RuntimeSALOME::UseCorba)
200 flags |= RuntimeSALOME::UsePython;
202 _useCorba = flags & RuntimeSALOME::UseCorba;
203 _usePython = flags & RuntimeSALOME::UsePython;
204 _useCpp = flags & RuntimeSALOME::UseCpp;
205 _useXml = flags & RuntimeSALOME::UseXml;
210 if (_useCpp) _setOfImplementation.insert(CppNode::IMPL_NAME);
211 if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
212 if (_useCorba) _setOfImplementation.insert(CORBANode::IMPL_NAME);
213 if (_useXml) _setOfImplementation.insert(XmlNode::IMPL_NAME);
214 init(flags, argc, argv);
217 RuntimeSALOME::~RuntimeSALOME()
219 DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
220 // destroy catalog loader prototypes
221 std::map<std::string, CatalogLoader*>::const_iterator pt;
222 for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
228 //! CORBA and Python initialization
230 * \param flags contains several bits
231 * bit0 (ispyext) true when method is called from Python
232 * (Python initialization must not be done!)
233 * bit1 (UsePython) true if python nodes are needed
234 * bit1 (UseCorba) true if CORBA nodes are needed
235 * bit1 (UseXml) true if python nodes are needed
236 * bit1 (UseCpp) true if C++ nodes are needed
237 * bit1 (UseSalome) true if Salome nodes are needed
238 * \param argc number of command line arguments (used to initialize the Python interpreter)
239 * \param argv command line arguments (used to initialize the Python interpreter)
243 void RuntimeSALOME::init(long flags, int argc, char* argv[])
245 bool ispyext = flags & RuntimeSALOME::IsPyExt;
248 PortableServer::POA_var root_poa;
249 PortableServer::POAManager_var pman;
250 CORBA::Object_var obj;
251 int nbargs = 0; char **args = 0;
252 _orb = CORBA::ORB_init (nbargs, args);
253 obj = _orb->resolve_initial_references("RootPOA");
254 root_poa = PortableServer::POA::_narrow(obj);
255 pman = root_poa->the_POAManager();
259 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
261 obj = _orb->resolve_initial_references("DynAnyFactory");
262 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
267 DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
269 // Initialize Python interpreter in embedded mode
270 if (!Py_IsInitialized())
272 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
275 Py_InitializeEx(0); // do not install signal handlers
277 if (argc > 0 && argv != NULL)
278 PySys_SetArgv(argc, argv);
283 char defaultName[] = "SALOME_YACS_RUNTIME";
284 pyArgv[0] = defaultName;
285 PySys_SetArgv(pyArgc, pyArgv);
287 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
288 PyEval_SaveThread(); /* Release the thread state */
289 //here we do not have the Global Interpreter Lock
292 PyObject *mainmod,*pyapi,*res ;
294 PyGILState_STATE gstate;
295 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
297 mainmod = PyImport_AddModule("__main__");
298 globals = PyModule_GetDict(mainmod);
299 /* globals is a borrowed reference */
301 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
303 PyObject *bimod = PyImport_ImportModule("__builtin__");
304 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
305 Py_FatalError("can't add __builtins__ to __main__");
309 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
315 _omnipy = PyImport_ImportModule((char*)"_omnipy");
319 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
322 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
327 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
330 res=PyRun_String("\n"
331 "from math import *\n"
333 "sys.path.insert(0,'.')\n"
334 "from omniORB import CORBA\n"
335 "from omniORB import any\n"
336 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
337 "#print sys.getrefcount(orb)\n"
343 Py_file_input,globals,globals );
351 _pyorb = PyDict_GetItemString(globals,"orb");
352 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
355 pyany = PyDict_GetItemString(globals,"any");
356 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
359 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
363 PyGILState_Release(gstate); // Release the Global Interpreter Lock
367 // initialize the catalogLoaderFactory map with the session one
368 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
372 void RuntimeSALOME::fini()
376 PyGILState_STATE gstate = PyGILState_Ensure();
378 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
380 PyObject *mainmod, *globals;
381 mainmod = PyImport_AddModule("__main__");
382 globals = PyModule_GetDict(mainmod);
386 res=PyRun_String("orb.destroy()\n"
388 Py_file_input,globals,globals );
394 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
395 delete nodeMap["PyFunction"];
396 delete nodeMap["PyScript"];
397 delete nodeMap["SalomePythonNode"];
398 nodeMap.erase("PyFunction");
399 nodeMap.erase("PyScript");
400 nodeMap.erase("SalomePythonNode");
404 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
412 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
419 std::string RuntimeSALOME::getVersion() const
421 #ifdef YACS_DEVELOPMENT
422 return CORBA::string_dup(YACS_VERSION_STR"dev");
424 return CORBA::string_dup(YACS_VERSION_STR);
428 Proc* RuntimeSALOME::createProc(const std::string& name)
430 return new SalomeProc(name);
433 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
434 std::list<TypeCodeObjref *> ltc)
437 if(id == "") myName = "IDL:" + name + ":1.0";
439 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
442 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
443 const std::string& name,
446 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
449 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
452 if(id == "") myName = "IDL:" + name + ":1.0";
454 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
457 Bloc* RuntimeSALOME::createBloc(const std::string& name)
459 return new Bloc(name);
462 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
464 return new WhileLoop(name);
467 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
469 return new ForLoop(name);
472 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
473 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
475 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
476 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
477 ol->edGetNbOfBranchesPort()->edInit(1);
481 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
486 node = new PresetNode(name);
489 else if(kind == "study" )
491 return new StudyInNode(name);
493 std::string msg="DataNode kind ("+kind+") unknown";
494 throw Exception(msg);
497 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
501 return new OutNode(name);
503 else if(kind == "study" )
505 return new StudyOutNode(name);
508 std::string msg="OutDataNode kind ("+kind+") unknown";
509 throw Exception(msg);
512 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
514 InlineFuncNode* node;
515 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
517 node = new PyFuncNode(name);
520 if(kind == DistributedPythonNode::KIND)
521 return new DistributedPythonNode(name);
522 std::string msg="FuncNode kind ("+kind+") unknown";
523 throw Exception(msg);
526 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
529 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
531 node = new PythonNode(name);
534 std::string msg="ScriptNode kind ("+kind+") unknown";
535 throw Exception(msg);
538 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
541 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
543 node = new CORBANode(name);
546 else if(kind == XmlNode::KIND)
548 node = new XmlNode(name);
551 std::string msg="RefNode kind ("+kind+") unknown";
552 throw Exception(msg);
555 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
558 if(kind == "" || kind == SalomeNode::KIND )
560 node=new SalomeNode(name);
563 else if (kind == CppNode::KIND)
565 node = new CppNode(name);
568 std::string msg="CompoNode kind ("+kind+") unknown";
569 throw Exception(msg);
572 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
574 if(kind == "" || kind == SalomeNode::KIND )
575 return new SalomePythonNode(name);
576 std::string msg="CompoNode kind ("+kind+") unknown";
577 throw Exception(msg);
580 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
581 const std::string& kind)
583 ComponentInstance* compo;
584 if(kind == "" || kind == SalomeComponent::KIND)
585 return new SalomeComponent(name);
586 else if(kind == CORBAComponent::KIND)
587 return new CORBAComponent(name);
588 else if(kind == SalomePythonComponent::KIND)
589 return new SalomePythonComponent(name);
590 else if (kind == CppComponent::KIND)
591 return new CppComponent(name);
592 else if (kind == SalomeHPComponent::KIND)
593 return new SalomeHPComponent(name);
594 std::string msg="Component Instance kind ("+kind+") unknown";
595 throw Exception(msg);
598 Container *RuntimeSALOME::createContainer(const std::string& kind)
600 if(kind == "" || kind == SalomeContainer::KIND)
601 return new SalomeContainer;
602 if(kind==SalomeHPContainer::KIND)
603 return new SalomeHPContainer;
604 else if (kind == CppContainer::KIND)
605 return new CppContainer;
606 std::string msg="Container kind ("+kind+") unknown";
607 throw Exception(msg);
610 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
611 const std::string& impl,
615 if(impl == CppNode::IMPL_NAME)
617 return new InputCppPort(name, node, type);
619 else if(impl == PythonNode::IMPL_NAME)
621 return new InputPyPort(name, node, type);
623 else if(impl == CORBANode::IMPL_NAME)
625 return new InputCorbaPort(name, node, type);
627 else if(impl == XmlNode::IMPL_NAME)
629 return new InputXmlPort(name, node, type);
634 msg << "Cannot create " << impl << " InputPort" ;
635 msg << " ("__FILE__ << ":" << __LINE__ << ")";
636 throw Exception(msg.str());
640 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
641 const std::string& impl,
645 if(impl == CppNode::IMPL_NAME)
647 return new OutputCppPort(name, node, type);
649 else if(impl == PythonNode::IMPL_NAME)
651 return new OutputPyPort(name, node, type);
653 else if(impl == CORBANode::IMPL_NAME)
655 return new OutputCorbaPort(name, node, type);
657 else if(impl == XmlNode::IMPL_NAME)
659 return new OutputXmlPort(name, node, type);
664 msg << "Cannot create " << impl << " OutputPort" ;
665 msg << " ("__FILE__ << ":" << __LINE__ << ")";
666 throw Exception(msg.str());
670 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
671 Node *node,TypeCode *type)
673 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
674 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
676 return new InputCalStreamPort(name,node,type);
680 return new InputDataStreamPort(name,node,type);
684 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
685 Node *node,TypeCode *type)
687 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
688 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
690 return new OutputCalStreamPort(name,node,type);
694 return new OutputDataStreamPort(name,node,type);
698 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
700 * \param source : InputPort to be adapted
701 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
702 * \param type : data type provided by the InputPort
703 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
705 * \return : adapted InputPort
707 InputPort* RuntimeSALOME::adapt(InputPort* source,
708 const std::string& impl,
709 TypeCode * type,bool init) throw (ConversionException)
711 string imp_source=source->getNode()->getImplementation();
712 if(imp_source == PythonNode::IMPL_NAME)
714 return adapt((InputPyPort*)source,impl,type,init);
716 else if(imp_source == CppNode::IMPL_NAME)
718 return adapt((InputCppPort*)source,impl,type,init);
720 else if(imp_source == CORBANode::IMPL_NAME)
722 return adapt((InputCorbaPort*)source,impl,type,init);
724 else if(imp_source == XmlNode::IMPL_NAME)
726 return adapt((InputXmlPort*)source,impl,type,init);
728 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
730 return adaptNeutral(source,impl,type,init);
735 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
736 msg << " ("__FILE__ << ":" << __LINE__ << ")";
737 throw ConversionException(msg.str());
741 //! Adapter function for InPropertyPort
743 * \param source : InPropertyPort to be adapted
744 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
745 * \param type : data type provided by the InPropertyPort
746 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
748 * \return : adapted InputPort
750 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
751 const std::string& impl,
752 TypeCode * type,bool init) throw (ConversionException)
754 return adaptNeutral((InputPort *)source,impl,type,init);
757 //! Adapt a Neutral input port to a Corba output port
759 * \param inport : Neutral input port to adapt to Corba type type
760 * \param type : output port type
761 * \return an adaptated input port of type InputCorbaPort
763 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
764 TypeCode * type) throw (ConversionException)
766 // BEWARE : using the generic check
767 if(inport->edGetType()->isAdaptable(type))
769 //the output data is convertible to inport type
770 return new CorbaNeutral(inport);
772 //non convertible type
774 msg << "Cannot connect Corba output port with type: " << type->id() ;
775 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
777 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
779 throw ConversionException(msg.str());
782 //! Adapt a Neutral input port to a Python output port
784 * \param inport : input port to adapt to Python type type
785 * \param type : output port type
786 * \return an adaptated input port of type InputPyPort
788 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
789 TypeCode * type) throw (ConversionException)
791 // BEWARE : using the generic check
792 if(inport->edGetType()->isAdaptable(type))
795 return new PyNeutral(inport);
797 //non convertible type
799 msg << "Cannot connect Python output port with type: " << type->id() ;
800 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
802 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
804 throw ConversionException(msg.str());
807 //! Adapt a Neutral input port to a Xml output port
809 * \param inport : input port to adapt to Xml type type
810 * \param type : output port type
811 * \return an input port of type InputXmlPort
813 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
814 TypeCode * type) throw (ConversionException)
816 // BEWARE : using the generic check
817 if(inport->edGetType()->isAdaptable(type))
820 return new XmlNeutral(inport);
822 //non convertible type
824 msg << "Cannot connect Xml output port with type: " << type->id() ;
825 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
827 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
829 throw ConversionException(msg.str());
832 //! Adapt a Neutral input port to a C++ output port
834 * \param inport : input port to adapt to C++ type type
835 * \param type : output port type
836 * \return an input port of type InputCppPort
838 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
839 TypeCode * type) throw (ConversionException)
841 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
842 if(isAdaptableNeutralCpp(type,inport->edGetType()))
845 return new CppNeutral(inport);
847 //non convertible type
849 msg << "Cannot connect Cpp output port with type: " << type->id() ;
850 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
852 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
854 throw ConversionException(msg.str());
857 //! Adapt a Neutral input port to connect it to an output port with a given implementation
859 * \param source : Neutral input port to adapt to implementation impl and type type
860 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
861 * \param type : output port supported type
862 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
863 * \return the adaptated port
865 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
866 const std::string& impl,
867 TypeCode * type,bool init) throw (ConversionException)
869 if(impl == CppNode::IMPL_NAME)
871 return adaptNeutralToCpp(source,type);
873 else if(impl == PythonNode::IMPL_NAME)
875 return adaptNeutralToPython(source,type);
877 else if(impl == CORBANode::IMPL_NAME)
879 return adaptNeutralToCorba(source,type);
881 else if(impl == XmlNode::IMPL_NAME )
883 return adaptNeutralToXml(source,type);
885 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
888 return new NeutralInit(source);
890 return new ProxyPort(source);
893 msg << "Cannot connect InputPort : unknown implementation " << impl;
894 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
895 throw ConversionException(msg.str());
898 //! Adapt a XML input port to connect it to a CORBA output port
900 * \param inport : input port to adapt to CORBA type type
901 * \param type : type supported by output port
902 * \return an adaptator port of type InputCorbaPort
905 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
906 TypeCode * type) throw (ConversionException)
908 if(isAdaptableXmlCorba(type,inport->edGetType()))
910 //output type is convertible to input type
911 return new CorbaXml(inport);
913 //output type is not convertible
915 msg << "Cannot connect Corba output port with type: " << type->id() ;
916 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
918 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
920 throw ConversionException(msg.str());
923 //! Adapt a XML input port to a Python output port
925 * \param inport : input port to adapt to Python type type
926 * \param type : output port type
927 * \return an adaptated input port of type InputPyPort
929 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
930 TypeCode * type) throw (ConversionException)
932 if(inport->edGetType()->isAdaptable(type))
934 //the output data is convertible to inport type
935 return new PyXml(inport);
937 //non convertible type
939 msg << "Cannot connect Python output port with type: " << type->id() ;
940 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
942 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
944 throw ConversionException(msg.str());
947 //! Adapt a XML input port to a C++ output port
949 * \param inport : input port to adapt to C++ type type
950 * \param type : output port type
951 * \return an adaptated input port of type InputPyPort
953 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
954 TypeCode * type) throw (ConversionException)
956 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
957 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
958 if(type->isAdaptable(inport->edGetType()))
960 //the output data is convertible to inport type
961 return new CppXml(inport);
963 //non convertible type
965 msg << "Cannot connect Cpp output port with type: " << type->id() ;
966 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
968 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
970 throw ConversionException(msg.str());
973 //! Adapt a XML input port to a Neutral output port
975 * \param inport : input port to adapt to Neutral type type
976 * \param type : output port type
977 * \return an adaptated input port of type Neutralxxxx
979 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
980 TypeCode * type) throw (ConversionException)
982 if(inport->edGetType()->isAdaptable(type))
984 //the output data is convertible to inport type
985 return new NeutralXml(inport);
987 //non convertible type
989 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
990 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
991 throw ConversionException(msg.str());
994 //! Adapt a XML input port to a Xml output port
996 * \param inport : input port to adapt to Xml type type
997 * \param type : output port type
998 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
999 * \return an adaptated input port of type Xmlxxxx
1001 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
1002 TypeCode * type,bool init) throw (ConversionException)
1005 return new ProxyPort(inport);
1007 if(inport->edGetType()->isAdaptable(type))
1008 return new ProxyPort(inport);
1011 msg << "Cannot connect Xml output port with type: " << type->id() ;
1012 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1014 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1016 throw ConversionException(msg.str());
1019 //! Adapt an Xml input port to an output port which implementation is given by impl
1021 * \param source : input port to adapt to implementation impl and type type
1022 * \param impl : output port implementation (C++, Python or Corba)
1023 * \param type : output port supported type
1024 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1025 * \return the adaptated port
1028 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1029 const std::string& impl,
1030 TypeCode * type,bool init) throw (ConversionException)
1032 if(impl == CORBANode::IMPL_NAME)
1034 return adaptXmlToCorba(source,type);
1036 else if(impl == PythonNode::IMPL_NAME)
1038 return adaptXmlToPython(source,type);
1040 else if(impl == CppNode::IMPL_NAME)
1042 return adaptXmlToCpp(source,type);
1044 else if(impl == XmlNode::IMPL_NAME )
1046 return adaptXmlToXml(source,type,init);
1048 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1050 return adaptXmlToNeutral(source,type);
1055 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1056 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1057 throw ConversionException(msg.str());
1062 //! Adapt a CORBA input port to a CORBA output port
1064 * \param inport : input port to adapt to CORBA outport data type
1065 * \param type : outport data type
1066 * \return an adaptator port of type InputCORBAPort
1068 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1069 TypeCode * type) throw (ConversionException)
1071 if(type->isA(inport->edGetType()))
1073 //types are compatible : no conversion
1074 //outport data type is more specific than inport required type
1075 //so the inport can be used safely
1076 return new ProxyPort(inport);
1078 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1080 //ouport data can be converted to inport data type
1081 return new CorbaCorba(inport);
1083 //outport data can not be converted
1085 msg << "Cannot connect Corba output port with type: " << type->id() ;
1086 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1088 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1090 throw ConversionException(msg.str());
1093 //! Adapt a CORBA input port to a Python output port
1095 * \param inport : input port to adapt to Python type type
1096 * \param type : outport data type
1097 * \return an adaptator port of type InputPyPort
1100 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1101 TypeCode * type) throw (ConversionException)
1103 if(inport->edGetType()->kind() == Double)
1105 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1107 else if(inport->edGetType()->kind() == Int)
1109 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1111 else if(inport->edGetType()->kind() == String)
1113 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1115 else if(inport->edGetType()->kind() == Bool)
1117 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1119 else if(inport->edGetType()->kind() == Objref )
1121 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1123 return new PyCorbaObjref(inport);
1128 msg << "Cannot connect Python output port with type: " << type->id() ;
1129 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1130 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1131 throw ConversionException(msg.str());
1134 else if(inport->edGetType()->kind() == Sequence)
1136 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1138 return new PyCorbaSequence(inport);
1143 msg << "Cannot convert this sequence type " ;
1144 msg << __FILE__ << ":" <<__LINE__;
1145 throw ConversionException(msg.str());
1148 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1150 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1152 return new PyCorbaStruct(inport);
1157 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1158 msg << __FILE__ << ":" <<__LINE__;
1159 throw ConversionException(msg.str());
1162 // Adaptation not possible
1164 msg << "Cannot connect Python output port with type: " << type->id() ;
1165 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1167 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1169 throw ConversionException(msg.str());
1172 //! Adapt a CORBA input port to connect it to a XML output port
1174 * \param inport : input port to adapt to Xml type type
1175 * \param type : type supported by output port
1176 * \return an adaptator port of type InputXmlPort
1179 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1180 TypeCode * type) throw (ConversionException)
1182 // BEWARE : using the generic check
1183 if(inport->edGetType()->isAdaptable(type))
1185 //output type is convertible to input type
1186 return new XmlCorba(inport);
1188 //output type is not convertible
1190 msg << "Cannot connect Xml output port with type: " << type->id() ;
1191 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1193 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1195 throw ConversionException(msg.str());
1198 //! Adapt a CORBA input port to a C++ output port
1200 * \param inport : input port to adapt to C++ type type
1201 * \param type : outport data type
1202 * \return an adaptator port of type InputCPPPort
1205 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1206 TypeCode * type) throw (ConversionException)
1208 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1209 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1211 //output type is convertible to input type
1212 return new CppCorba(inport);
1214 //output type is not convertible
1216 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1217 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1219 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1221 throw ConversionException(msg.str());
1224 //! Adapt a CORBA input port to a neutral data
1226 * \param inport : InputPort to adapt to Neutral type type
1227 * \param type : outport data type
1228 * \return an adaptator port of type Neutralxxxx
1231 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1232 TypeCode * type) throw (ConversionException)
1234 if(inport->edGetType()->kind() == Double)
1236 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1238 else if(inport->edGetType()->kind() == Int)
1240 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1242 else if(inport->edGetType()->kind() == String)
1244 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1246 else if(inport->edGetType()->kind() == Bool)
1248 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1250 else if(inport->edGetType()->kind() == Objref)
1252 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1254 else if(inport->edGetType()->kind() == Sequence)
1256 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1257 return new NeutralCorbaSequence(inport);
1261 msg << "Cannot convert this sequence type " ;
1262 msg << __FILE__ << ":" <<__LINE__;
1263 throw ConversionException(msg.str());
1266 else if(inport->edGetType()->kind() == Struct)
1268 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1271 // Adaptation not possible
1273 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1274 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1276 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1278 throw ConversionException(msg.str());
1281 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1283 * \param source : input port to adapt to implementation impl and type type
1284 * \param impl : output port implementation (C++, Python or Corba)
1285 * \param type : outport data type
1286 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1287 * \return an adaptator port which type depends on impl
1290 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1291 const std::string& impl,
1292 TypeCode * type,bool init) throw (ConversionException)
1294 if(impl == CppNode::IMPL_NAME)
1296 return adaptCorbaToCpp(source,type);
1298 else if(impl == PythonNode::IMPL_NAME)
1300 return adaptCorbaToPython(source,type);
1302 else if(impl == CORBANode::IMPL_NAME)
1305 return adaptCorbaToCorba(source,type);
1307 return adaptCorbaToCorba(source,type);
1309 else if(impl == XmlNode::IMPL_NAME )
1311 return adaptCorbaToXml(source,type);
1313 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1315 return adaptCorbaToNeutral(source,type);
1320 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1321 msg << __FILE__ << ":" <<__LINE__;
1322 throw ConversionException(msg.str());
1326 //! Adapt a Python input port to a Python output port
1328 * No need to make conversion or cast.
1329 * Only check, it's possible.
1330 * \param inport : InputPort to adapt to Python type type
1331 * \param type : outport data type
1332 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1333 * \return an adaptator port of type InputPyPort
1336 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1337 TypeCode * type,bool init) throw (ConversionException)
1340 return new PyInit(inport);
1342 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1344 //output data is convertible to input type
1345 //With python, no need to convert. Conversion will be done automatically
1346 //by the interpreter
1347 return new ProxyPort(inport);
1349 //output data is not convertible to input type
1351 msg << "Cannot connect Python output port with type: " << type->id() ;
1352 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1354 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1356 throw ConversionException(msg.str());
1359 //! Adapt a Python input port to a C++ output port
1361 * \param inport : InputPort to adapt to C++ type type
1362 * \param type : outport data type
1363 * \return an adaptator port of C++ type (InputCppPort)
1366 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1367 TypeCode * type) throw (ConversionException)
1369 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1370 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1372 //output type is convertible to input type
1373 return new CppPy(inport);
1375 //output type is not convertible
1377 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1378 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1380 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1382 throw ConversionException(msg.str());
1385 //! Adapt a Python input port to a Neutral data port
1387 * \param inport : InputPort to adapt to Neutral type type
1388 * \param type : outport data type
1389 * \return an adaptator port of Neutral type (Neutralxxxx)
1392 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1393 TypeCode * type) throw (ConversionException)
1395 if(inport->edGetType()->kind() == Double)
1397 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1399 else if(inport->edGetType()->kind() == Int)
1401 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1403 else if(inport->edGetType()->kind() == String)
1405 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1407 else if(inport->edGetType()->kind() == Bool)
1409 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1411 else if(inport->edGetType()->kind() == Objref)
1413 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1415 else if(inport->edGetType()->kind() == Sequence)
1417 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1418 return new NeutralPySequence(inport);
1422 msg << "Cannot convert this sequence type " ;
1423 msg << __FILE__ << ":" <<__LINE__;
1424 throw ConversionException(msg.str());
1427 else if(inport->edGetType()->kind() == Struct)
1429 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1432 // Adaptation not possible
1434 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1435 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1437 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1439 throw ConversionException(msg.str());
1442 //! Adapt a Python input port to a Corba output port
1444 * Always convert the data
1445 * \param inport : InputPort to adapt to Corba type type
1446 * \param type : outport data type
1447 * \return an adaptator port of Corba type (InputCorbaPort)
1450 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1451 TypeCode * type) throw (ConversionException)
1453 if(inport->edGetType()->kind() == Double)
1455 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1457 else if(inport->edGetType()->kind() == Int)
1459 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1461 else if(inport->edGetType()->kind() == String)
1463 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1465 else if(inport->edGetType()->kind() == Bool)
1467 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1469 else if(inport->edGetType()->kind() == Objref)
1471 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1473 return new CorbaPyObjref(inport);
1478 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1479 msg << " " << __FILE__ << ":" <<__LINE__;
1480 throw ConversionException(msg.str());
1483 else if(inport->edGetType()->kind() == Sequence)
1485 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1487 return new CorbaPySequence(inport);
1492 msg << "Cannot convert this sequence type " ;
1493 msg << __FILE__ << ":" <<__LINE__;
1494 throw ConversionException(msg.str());
1497 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1499 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1501 return new CorbaPyStruct(inport);
1506 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1507 msg << " " << __FILE__ << ":" <<__LINE__;
1508 throw ConversionException(msg.str());
1511 // Adaptation not possible
1513 msg << "Cannot connect Corba output port with type: " << type->id() ;
1514 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1516 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1518 throw ConversionException(msg.str());
1521 //! Adapt a Python input port to a Xml output port
1523 * \param inport : input port to adapt to Xml type type
1524 * \param type : output port type
1525 * \return an input port of type InputXmlPort
1528 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1529 TypeCode * type) throw (ConversionException)
1531 // BEWARE : using the generic check
1532 if(inport->edGetType()->isAdaptable(type))
1535 return new XmlPython(inport);
1537 //non convertible type
1539 msg << "Cannot connect Xml output port with type: " << type->id() ;
1540 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1542 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1544 throw ConversionException(msg.str());
1547 //! Adapt a Python input port to an output port with a given implementation
1549 * \param source : input port to adapt to implementation impl and type type
1550 * \param impl : output port implementation (C++, Python or Corba)
1551 * \param type : output port type
1552 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1553 * \return adaptated input port
1556 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1557 const std::string& impl,
1558 TypeCode * type,bool init) throw (ConversionException)
1560 if(impl == CppNode::IMPL_NAME)
1562 return adaptPythonToCpp(source,type);
1564 else if(impl == PythonNode::IMPL_NAME)
1566 return adaptPythonToPython(source,type,init);
1568 else if(impl == CORBANode::IMPL_NAME)
1570 return adaptPythonToCorba(source,type);
1572 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1574 return adaptPythonToNeutral(source,type);
1576 else if(impl == XmlNode::IMPL_NAME)
1578 return adaptPythonToXml(source,type);
1583 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1584 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1585 throw ConversionException(msg.str());
1590 //! Adapt a C++ input port to connect it to a CORBA output port
1592 * \param inport : input port to adapt to CORBA type type
1593 * \param type : type supported by output port
1594 * \return an adaptator port of type InputCorbaPort
1597 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1598 TypeCode * type) throw (ConversionException)
1600 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1601 if(isAdaptableCppCorba(type,inport->edGetType()))
1603 //output type is convertible to input type
1604 return new CorbaCpp(inport);
1606 //output type is not convertible
1608 msg << "Cannot connect Corba output port with type: " << type->id() ;
1609 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1611 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1613 throw ConversionException(msg.str());
1616 //! Adapt a C++ input port to a Python output port
1618 * \param inport : input port to adapt to Python type type
1619 * \param type : output port type
1620 * \return an adaptated input port of type InputPyPort
1622 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1623 TypeCode * type) throw (ConversionException)
1625 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1626 if(isAdaptableCppPyObject(type,inport->edGetType()))
1628 //output type is convertible to input type
1629 return new PyCpp(inport);
1631 //output type is not convertible
1633 msg << "Cannot connect Python output port with type: " << type->id() ;
1634 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1636 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1638 throw ConversionException(msg.str());
1641 //! Adapt a C++ input port to a C++ output port
1643 * \param inport : input port to adapt to C++ type type
1644 * \param type : output port type
1645 * \return an adaptated input port of type InputPyPort
1647 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1648 TypeCode * type) throw (ConversionException)
1650 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1651 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1652 if(type->isAdaptable(inport->edGetType()))
1654 //the output data is convertible to inport type
1655 return new CppCpp(inport);
1657 //non convertible type
1659 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1660 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1662 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1664 throw ConversionException(msg.str());
1667 //! Adapt a C++ input port to a Neutral output port
1669 * \param inport : input port to adapt to C++ type type
1670 * \param type : output port type
1671 * \return an adaptated input port of type InputPyPort
1673 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1674 TypeCode * type) throw (ConversionException)
1676 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1677 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1678 if(type->isAdaptable(inport->edGetType()))
1680 //the output data is convertible to inport type
1681 return new NeutralCpp(inport);
1683 //non convertible type
1685 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1686 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1688 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1690 throw ConversionException(msg.str());
1693 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1694 TypeCode * type) throw (ConversionException)
1696 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1697 if(isAdaptableCppXml(type,inport->edGetType()))
1700 return new XmlCpp(inport);
1702 //non convertible type
1704 msg << "Cannot connect Xml output port with type: " << type->id() ;
1705 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1707 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1709 throw ConversionException(msg.str());
1712 //! Adapt a C++ input port to connect it to an output port with a given implementation
1714 * \param source : input port to adapt to implementation impl and type type
1715 * \param impl : output port implementation (C++, Python or Corba)
1716 * \param type : output port supported type
1717 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1718 * \return the adaptated port
1721 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1722 const std::string& impl,
1723 TypeCode * type,bool init) throw (ConversionException)
1725 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1726 if(impl == CORBANode::IMPL_NAME)
1728 return adaptCppToCorba(source,type);
1730 else if(impl == PythonNode::IMPL_NAME)
1732 return adaptCppToPython(source,type);
1734 else if(impl == XmlNode::IMPL_NAME)
1736 return adaptCppToXml(source,type);
1738 else if(impl == CppNode::IMPL_NAME)
1740 return adaptCppToCpp(source, type);
1742 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1744 return adaptCppToNeutral(source, type);
1749 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1750 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1751 throw ConversionException(msg.str());
1755 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1756 // const InputPort* inputPort)
1758 // bool result=true;
1762 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1767 PyObject * RuntimeSALOME::getPyOrb()
1772 PyObject * RuntimeSALOME::getBuiltins()
1777 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1782 PyObject * RuntimeSALOME::get_omnipy()
1787 omniORBpyAPI* RuntimeSALOME::getApi()
1792 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1795 return (void *)convertNeutralPyObject(type,data);
1799 return (void *)Py_None;
1803 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1808 ob=convertNeutralPyObject(type,data);
1809 std::string s=convertPyObjectToString(ob);
1811 // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1812 // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1813 // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1814 // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1815 // feel free to change this code.
1816 PyGILState_STATE gstate = PyGILState_Ensure();
1818 PyGILState_Release(gstate);
1827 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1829 return YACS::ENGINE::convertPyObjectToString(ob);
1832 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1837 PyGILState_STATE gstate = PyGILState_Ensure();
1838 mainmod = PyImport_AddModule("__main__");
1839 globals = PyModule_GetDict(mainmod);
1840 PyObject* d = PyDict_New();
1841 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1842 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1848 PyObject* new_stderr = newPyStdOut(error);
1849 PySys_SetObject((char *)"stderr", new_stderr);
1851 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1852 Py_DECREF(new_stderr);
1853 PyGILState_Release(gstate);
1854 throw Exception(error);
1856 PyGILState_Release(gstate);