1 // Copyright (C) 2006-2021 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"
47 #include "SalomeProc.hxx"
48 #include "PyStdout.hxx"
50 #include "SessionCataLoader.hxx"
53 #include "CORBAComponent.hxx"
54 #include "SalomeComponent.hxx"
55 #include "SalomeHPComponent.hxx"
56 #include "SalomePythonComponent.hxx"
57 #include "CppComponent.hxx"
59 #include "SalomeContainer.hxx"
60 #include "CppContainer.hxx"
61 #include "SalomeHPContainer.hxx"
64 #include "PythonNode.hxx"
65 #include "CORBANode.hxx"
66 #include "XMLNode.hxx"
67 #include "CppNode.hxx"
68 #include "PresetNode.hxx"
69 #include "OutNode.hxx"
70 #include "StudyNodes.hxx"
71 #include "SalomePythonNode.hxx"
72 #include "DistributedPythonNode.hxx"
75 #include "CORBACORBAConv.hxx"
76 #include "CORBAPythonConv.hxx"
77 #include "CORBAXMLConv.hxx"
78 #include "CORBACppConv.hxx"
79 #include "CORBANeutralConv.hxx"
81 #include "TypeConversions.hxx"
83 #include "PythonCORBAConv.hxx"
84 #include "PythonXMLConv.hxx"
85 #include "PythonCppConv.hxx"
86 #include "PythonNeutralConv.hxx"
87 #include "PythonInitConv.hxx"
90 #include "NeutralCORBAConv.hxx"
91 #include "NeutralPythonConv.hxx"
92 #include "NeutralXMLConv.hxx"
93 #include "NeutralCppConv.hxx"
94 #include "NeutralInitConv.hxx"
97 #include "CppCORBAConv.hxx"
98 #include "CppPythonConv.hxx"
99 #include "CppXMLConv.hxx"
100 #include "CppCppConv.hxx"
101 #include "CppNeutralConv.hxx"
104 #include "XMLCORBAConv.hxx"
105 #include "XMLPythonConv.hxx"
106 #include "XMLCppConv.hxx"
107 #include "XMLNeutralConv.hxx"
109 //Calcium specific ports
110 #include "CalStreamPort.hxx"
113 #include "SALOME_NamingService.hxx"
114 #include "SALOME_LifeCycleCORBA.hxx"
115 #include "SALOME_NamingService.hxx"
116 #include "SALOME_ResourcesManager.hxx"
117 #include "SALOME_ContainerManager.hxx"
118 #include "SALOMEconfig.h"
119 #include CORBA_CLIENT_HEADER(SALOME_ContainerManager)
123 #include <libxml/parser.h>
124 #include <omniORB4/CORBA.h>
130 #include "YacsTrace.hxx"
133 using namespace YACS::ENGINE;
135 void RuntimeSALOME::setRuntime(long flags, int argc, char* argv[]) // singleton creation (not thread safe!)
137 if (! Runtime::_singleton)
139 RuntimeSALOME* r=new RuntimeSALOME(flags, argc, argv);
140 Runtime::_singleton = r;
143 DEBTRACE("RuntimeSALOME::setRuntime() done !");
146 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
148 YASSERT(RuntimeSALOME::getSingleton());
149 return dynamic_cast< RuntimeSALOME* >(RuntimeSALOME::getSingleton());
153 * Singleton creation, initialize converter map
156 RuntimeSALOME::RuntimeSALOME()
161 void RuntimeSALOME::initBuiltins()
163 //Fill the builtin catalog with nodes specific to the runtime
164 std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
165 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
166 std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
167 std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
168 nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
169 nodeMap["PyScript"]=new PythonNode("PyScript");
170 nodeMap["CORBANode"]=new CORBANode("CORBANode");
171 nodeMap["XmlNode"]=new XmlNode("XmlNode");
172 nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
173 nodeMap["CppNode"]=new CppNode("CppNode");
174 nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
175 nodeMap["PresetNode"]=new PresetNode("PresetNode");
176 nodeMap["OutNode"]=new OutNode("OutNode");
177 nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
178 nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
179 composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
180 typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
181 typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
182 typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
183 typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
184 typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
185 typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
186 typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
187 typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
188 std::list<TypeCodeObjref *> ltc;
189 typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
190 typeMap["seqpyobj"]= createSequenceTc("seqpyobj","seqpyobj",typeMap["pyobj"]);
191 composednodeMap["Bloc"]=createBloc("Bloc");
192 composednodeMap["Switch"]=createSwitch("Switch");
193 composednodeMap["WhileLoop"]=createWhileLoop("WhileLoop");
194 composednodeMap["ForLoop"]=createForLoop("ForLoop");
195 composednodeMap["ForEachLoop_double"]=createForEachLoop("ForEachLoop_double",Runtime::_tc_double);
196 composednodeMap["ForEachLoop_string"]=createForEachLoop("ForEachLoop_string",Runtime::_tc_string);
197 composednodeMap["ForEachLoop_int"]=createForEachLoop("ForEachLoop_int",Runtime::_tc_int);
198 composednodeMap["ForEachLoop_bool"]=createForEachLoop("ForEachLoop_bool",Runtime::_tc_bool);
199 composednodeMap["ForEachLoop_pyobj"]=createForEachLoop("ForEachLoop_pyobj",typeMap["pyobj"]);;
200 ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
201 t->addMember("ref",_tc_string);
202 typeMap["dataref"]= t;
205 RuntimeSALOME::RuntimeSALOME(long flags, int argc, char* argv[])
207 // If all flags (apart the IsPyExt flags) are unset, force them to true
208 if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
209 flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
210 + RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
212 // Salome Nodes implies Corba Nodes
213 if (flags & RuntimeSALOME::UseSalome)
214 flags |= RuntimeSALOME::UseCorba;
216 // Corba Nodes implies Python Nodes
217 if (flags & RuntimeSALOME::UseCorba)
218 flags |= RuntimeSALOME::UsePython;
220 _useCorba = flags & RuntimeSALOME::UseCorba;
221 _usePython = flags & RuntimeSALOME::UsePython;
222 _useCpp = flags & RuntimeSALOME::UseCpp;
223 _useXml = flags & RuntimeSALOME::UseXml;
228 if (_useCpp) _setOfImplementation.insert(CppNode::IMPL_NAME);
229 if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
230 if (_useCorba) _setOfImplementation.insert(CORBANode::IMPL_NAME);
231 if (_useXml) _setOfImplementation.insert(XmlNode::IMPL_NAME);
232 init(flags, argc, argv);
235 RuntimeSALOME::~RuntimeSALOME()
237 DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
238 // destroy catalog loader prototypes
239 std::map<std::string, CatalogLoader*>::const_iterator pt;
240 for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
246 //! CORBA and Python initialization
248 * \param flags contains several bits
249 * bit0 (ispyext) true when method is called from Python
250 * (Python initialization must not be done!)
251 * bit1 (UsePython) true if python nodes are needed
252 * bit1 (UseCorba) true if CORBA nodes are needed
253 * bit1 (UseXml) true if python nodes are needed
254 * bit1 (UseCpp) true if C++ nodes are needed
255 * bit1 (UseSalome) true if Salome nodes are needed
256 * \param argc number of command line arguments (used to initialize the Python interpreter)
257 * \param argv command line arguments (used to initialize the Python interpreter)
261 void RuntimeSALOME::init(long flags, int argc, char* argv[])
263 bool ispyext = flags & RuntimeSALOME::IsPyExt;
266 PortableServer::POA_var root_poa;
267 PortableServer::POAManager_var pman;
268 CORBA::Object_var obj;
269 int nbargs = 0; char **args = 0;
270 _orb = CORBA::ORB_init (nbargs, args);
271 obj = _orb->resolve_initial_references("RootPOA");
272 root_poa = PortableServer::POA::_narrow(obj);
273 pman = root_poa->the_POAManager();
277 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
279 obj = _orb->resolve_initial_references("DynAnyFactory");
280 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
285 DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
287 // Initialize Python interpreter in embedded mode
288 if (!Py_IsInitialized())
290 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
293 Py_InitializeEx(0); // do not install signal handlers
295 if (argc > 0 && argv != NULL)
297 wchar_t **changed_argv = new wchar_t*[argc];
298 for (int i = 0; i < argc; i++)
300 changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
302 PySys_SetArgv(argc, changed_argv);
308 char defaultName[] = "SALOME_YACS_RUNTIME";
309 wchar_t **changed_pyArgv = new wchar_t*[pyArgc];
310 pyArgv[0] = defaultName;
311 for (int i = 0; i < pyArgc; i++)
313 changed_pyArgv[i] = Py_DecodeLocale(pyArgv[i], NULL);
315 PySys_SetArgv(pyArgc, changed_pyArgv);
317 #if PY_VERSION_HEX < 0x03070000
318 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
320 PyEval_SaveThread(); /* Release the thread state */
321 //here we do not have the Global Interpreter Lock
324 PyObject *mainmod,*pyapi,*res ;
326 PyGILState_STATE gstate;
327 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
329 mainmod = PyImport_AddModule("__main__");
330 globals = PyModule_GetDict(mainmod);
331 /* globals is a borrowed reference */
333 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
335 PyObject *bimod = PyImport_ImportModule("builtins");
336 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
337 Py_FatalError("can't add __builtins__ to __main__");
341 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
347 _omnipy = PyImport_ImportModule((char*)"_omnipy");
351 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
354 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
359 _api = (omniORBpyAPI*)PyCapsule_GetPointer(pyapi,"_omnipy.API");
362 res=PyRun_String("\n"
363 "from math import *\n"
365 "sys.path.insert(0,'.')\n"
366 "from omniORB import CORBA\n"
367 "from omniORB import any\n"
368 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
369 "#print(sys.getrefcount(orb))\n"
375 Py_file_input,globals,globals );
383 _pyorb = PyDict_GetItemString(globals,"orb");
384 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
387 pyany = PyDict_GetItemString(globals,"any");
388 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
391 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
395 PyGILState_Release(gstate); // Release the Global Interpreter Lock
399 // initialize the catalogLoaderFactory map with the session one
400 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
404 void RuntimeSALOME::fini()
408 PyGILState_STATE gstate = PyGILState_Ensure();
410 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
412 PyObject *mainmod, *globals;
413 mainmod = PyImport_AddModule("__main__");
414 globals = PyModule_GetDict(mainmod);
418 res=PyRun_String("orb.destroy()\n"
420 Py_file_input,globals,globals );
426 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
427 delete nodeMap["PyFunction"];
428 delete nodeMap["PyScript"];
429 delete nodeMap["SalomePythonNode"];
430 nodeMap.erase("PyFunction");
431 nodeMap.erase("PyScript");
432 nodeMap.erase("SalomePythonNode");
436 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
444 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
451 std::vector< std::pair<std::string,int> > RuntimeSALOME::getCatalogOfComputeNodes() const
453 CORBA::ORB_ptr orb(getOrb());
454 SALOME_NamingService namingService;
457 namingService.init_orb(orb);
459 catch(SALOME_Exception& e)
461 throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Unable to contact the SALOME Naming Service");
463 CORBA::Object_var obj(namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS));
464 if(CORBA::is_nil(obj))
465 throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Unable to access to the resource manager !");
466 Engines::ResourcesManager_var resManager(Engines::ResourcesManager::_narrow(obj));
467 if(CORBA::is_nil(resManager))
468 throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Internal error ! The entry attached to the res manager in NS does not have right type !");
469 std::vector< std::pair<std::string,int> > ret;
470 Engines::ResourceParameters params;
472 params.hostname = "";
476 params.cpu_clock = 0;
478 params.nb_proc_per_node = 0;
480 params.can_launch_batch_jobs = false;
481 params.can_run_containers = true;
482 params.componentList.length(0);
485 Engines::ResourceList_var resourceList;
486 resourceList = resManager->GetFittingResources(params);
487 ret.reserve(resourceList->length());
488 for(int i = 0; i<resourceList->length(); i++)
490 const char* resource_name = resourceList[i];
491 std::string std_resource_name = resource_name;
492 Engines::ResourceDefinition_var resource_definition
493 = resManager->GetResourceDefinition(resource_name);
494 int nb_cores = resource_definition->nb_node *
495 resource_definition->nb_proc_per_node;
496 ret.push_back(std::pair<std::string,int>(resource_name, nb_cores));
499 catch(SALOME::SALOME_Exception& e)
502 message=e.details.text.in();
503 throw Exception(message);
509 std::string RuntimeSALOME::getVersion() const
511 #ifdef YACS_DEVELOPMENT
512 return CORBA::string_dup(YACS_VERSION_STR"dev");
514 return CORBA::string_dup(YACS_VERSION_STR);
518 Proc* RuntimeSALOME::createProc(const std::string& name)
520 return new SalomeProc(name);
523 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
524 std::list<TypeCodeObjref *> ltc)
527 if(id == "") myName = "IDL:" + name + ":1.0";
529 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
532 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
533 const std::string& name,
536 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
539 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
542 if(id == "") myName = "IDL:" + name + ":1.0";
544 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
547 Bloc* RuntimeSALOME::createBloc(const std::string& name)
549 return new Bloc(name);
552 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
554 return new WhileLoop(name);
557 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
559 return new ForLoop(name);
562 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
563 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
565 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
566 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
567 ol->edGetNbOfBranchesPort()->edInit(1);
571 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
576 node = new PresetNode(name);
579 else if(kind == "study" )
581 return new StudyInNode(name);
583 std::string msg="DataNode kind ("+kind+") unknown";
584 throw Exception(msg);
587 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
591 return new OutNode(name);
593 else if(kind == "study" )
595 return new StudyOutNode(name);
598 std::string msg="OutDataNode kind ("+kind+") unknown";
599 throw Exception(msg);
602 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
604 InlineFuncNode* node;
605 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
607 node = new PyFuncNode(name);
610 if(kind == DistributedPythonNode::KIND)
611 return new DistributedPythonNode(name);
612 std::string msg="FuncNode kind ("+kind+") unknown";
613 throw Exception(msg);
616 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
619 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
621 node = new PythonNode(name);
624 std::string msg="ScriptNode kind ("+kind+") unknown";
625 throw Exception(msg);
628 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
631 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
633 node = new CORBANode(name);
636 else if(kind == XmlNode::KIND)
638 node = new XmlNode(name);
641 std::string msg="RefNode kind ("+kind+") unknown";
642 throw Exception(msg);
645 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
648 if(kind == "" || kind == SalomeNode::KIND )
650 node=new SalomeNode(name);
653 else if (kind == CppNode::KIND)
655 node = new CppNode(name);
658 std::string msg="CompoNode kind ("+kind+") unknown";
659 throw Exception(msg);
662 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
664 if(kind == "" || kind == SalomeNode::KIND )
665 return new SalomePythonNode(name);
666 std::string msg="CompoNode kind ("+kind+") unknown";
667 throw Exception(msg);
670 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
671 const std::string& kind)
673 ComponentInstance* compo;
674 if(kind == "" || kind == SalomeComponent::KIND)
675 return new SalomeComponent(name);
676 else if(kind == CORBAComponent::KIND)
677 return new CORBAComponent(name);
678 else if(kind == SalomePythonComponent::KIND)
679 return new SalomePythonComponent(name);
680 else if (kind == CppComponent::KIND)
681 return new CppComponent(name);
682 else if (kind == SalomeHPComponent::KIND)
683 return new SalomeHPComponent(name);
684 std::string msg="Component Instance kind ("+kind+") unknown";
685 throw Exception(msg);
688 Container *RuntimeSALOME::createContainer(const std::string& kind)
690 if(kind == "" || kind == SalomeContainer::KIND)
691 return new SalomeContainer;
692 if(kind==SalomeHPContainer::KIND)
693 return new SalomeHPContainer;
694 else if (kind == CppContainer::KIND)
695 return new CppContainer;
696 std::string msg="Container kind ("+kind+") unknown";
697 throw Exception(msg);
700 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
701 const std::string& impl,
705 if(impl == CppNode::IMPL_NAME)
707 return new InputCppPort(name, node, type);
709 else if(impl == PythonNode::IMPL_NAME)
711 return new InputPyPort(name, node, type);
713 else if(impl == CORBANode::IMPL_NAME)
715 return new InputCorbaPort(name, node, type);
717 else if(impl == XmlNode::IMPL_NAME)
719 return new InputXmlPort(name, node, type);
724 msg << "Cannot create " << impl << " InputPort" ;
725 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
726 throw Exception(msg.str());
730 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
731 const std::string& impl,
735 if(impl == CppNode::IMPL_NAME)
737 return new OutputCppPort(name, node, type);
739 else if(impl == PythonNode::IMPL_NAME)
741 return new OutputPyPort(name, node, type);
743 else if(impl == CORBANode::IMPL_NAME)
745 return new OutputCorbaPort(name, node, type);
747 else if(impl == XmlNode::IMPL_NAME)
749 return new OutputXmlPort(name, node, type);
754 msg << "Cannot create " << impl << " OutputPort" ;
755 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
756 throw Exception(msg.str());
760 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
761 Node *node,TypeCode *type)
763 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
764 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
766 return new InputCalStreamPort(name,node,type);
770 return new InputDataStreamPort(name,node,type);
774 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
775 Node *node,TypeCode *type)
777 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
778 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
780 return new OutputCalStreamPort(name,node,type);
784 return new OutputDataStreamPort(name,node,type);
788 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
790 * \param source : InputPort to be adapted
791 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
792 * \param type : data type provided by the InputPort
793 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
795 * \return : adapted InputPort
797 InputPort* RuntimeSALOME::adapt(InputPort* source,
798 const std::string& impl,
799 TypeCode * type,bool init)
801 string imp_source=source->getNode()->getImplementation();
802 if(imp_source == PythonNode::IMPL_NAME)
804 return adapt((InputPyPort*)source,impl,type,init);
806 else if(imp_source == CppNode::IMPL_NAME)
808 return adapt((InputCppPort*)source,impl,type,init);
810 else if(imp_source == CORBANode::IMPL_NAME)
812 return adapt((InputCorbaPort*)source,impl,type,init);
814 else if(imp_source == XmlNode::IMPL_NAME)
816 return adapt((InputXmlPort*)source,impl,type,init);
818 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
820 return adaptNeutral(source,impl,type,init);
825 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
826 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
827 throw ConversionException(msg.str());
831 //! Adapter function for InPropertyPort
833 * \param source : InPropertyPort to be adapted
834 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
835 * \param type : data type provided by the InPropertyPort
836 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
838 * \return : adapted InputPort
840 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
841 const std::string& impl,
842 TypeCode * type,bool init)
844 return adaptNeutral((InputPort *)source,impl,type,init);
847 //! Adapt a Neutral input port to a Corba output port
849 * \param inport : Neutral input port to adapt to Corba type type
850 * \param type : output port type
851 * \return an adaptated input port of type InputCorbaPort
853 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
856 // BEWARE : using the generic check
857 if(inport->edGetType()->isAdaptable(type))
859 //the output data is convertible to inport type
860 return new CorbaNeutral(inport);
862 //non convertible type
864 msg << "Cannot connect Corba output port with type: " << type->id() ;
865 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
867 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
869 throw ConversionException(msg.str());
872 //! Adapt a Neutral input port to a Python output port
874 * \param inport : input port to adapt to Python type type
875 * \param type : output port type
876 * \return an adaptated input port of type InputPyPort
878 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
881 // BEWARE : using the generic check
882 if(inport->edGetType()->isAdaptable(type))
885 return new PyNeutral(inport);
887 //last chance : an py output that is seq[objref] can be connected to a neutral input objref (P13268)
888 else if(type->kind()==Sequence && type->contentType()->kind()==Objref && inport->edGetType()->kind()==Objref)
890 return new PyNeutral(inport);
892 //non convertible type
894 msg << "Cannot connect Python output port with type: " << type->id() ;
895 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
897 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
899 throw ConversionException(msg.str());
902 //! Adapt a Neutral input port to a Xml output port
904 * \param inport : input port to adapt to Xml type type
905 * \param type : output port type
906 * \return an input port of type InputXmlPort
908 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
911 // BEWARE : using the generic check
912 if(inport->edGetType()->isAdaptable(type))
915 return new XmlNeutral(inport);
917 //non convertible type
919 msg << "Cannot connect Xml output port with type: " << type->id() ;
920 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
922 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
924 throw ConversionException(msg.str());
927 //! Adapt a Neutral input port to a C++ output port
929 * \param inport : input port to adapt to C++ type type
930 * \param type : output port type
931 * \return an input port of type InputCppPort
933 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
936 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
937 if(isAdaptableNeutralCpp(type,inport->edGetType()))
940 return new CppNeutral(inport);
942 //non convertible type
944 msg << "Cannot connect Cpp output port with type: " << type->id() ;
945 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
947 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
949 throw ConversionException(msg.str());
952 //! Adapt a Neutral input port to connect it to an output port with a given implementation
954 * \param source : Neutral input port to adapt to implementation impl and type type
955 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
956 * \param type : output port supported type
957 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
958 * \return the adaptated port
960 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
961 const std::string& impl,
962 TypeCode * type,bool init)
964 if(impl == CppNode::IMPL_NAME)
966 return adaptNeutralToCpp(source,type);
968 else if(impl == PythonNode::IMPL_NAME)
970 return adaptNeutralToPython(source,type);
972 else if(impl == CORBANode::IMPL_NAME)
974 return adaptNeutralToCorba(source,type);
976 else if(impl == XmlNode::IMPL_NAME )
978 return adaptNeutralToXml(source,type);
980 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
983 return new NeutralInit(source);
985 return new ProxyPort(source);
988 msg << "Cannot connect InputPort : unknown implementation " << impl;
989 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
990 throw ConversionException(msg.str());
993 //! Adapt a XML input port to connect it to a CORBA output port
995 * \param inport : input port to adapt to CORBA type type
996 * \param type : type supported by output port
997 * \return an adaptator port of type InputCorbaPort
1000 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
1003 if(isAdaptableXmlCorba(type,inport->edGetType()))
1005 //output type is convertible to input type
1006 return new CorbaXml(inport);
1008 //output type is not convertible
1010 msg << "Cannot connect Corba output port with type: " << type->id() ;
1011 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1013 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1015 throw ConversionException(msg.str());
1018 //! Adapt a XML input port to a Python output port
1020 * \param inport : input port to adapt to Python type type
1021 * \param type : output port type
1022 * \return an adaptated input port of type InputPyPort
1024 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
1027 if(inport->edGetType()->isAdaptable(type))
1029 //the output data is convertible to inport type
1030 return new PyXml(inport);
1032 //non convertible type
1034 msg << "Cannot connect Python output port with type: " << type->id() ;
1035 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1037 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1039 throw ConversionException(msg.str());
1042 //! Adapt a XML input port to a C++ output port
1044 * \param inport : input port to adapt to C++ type type
1045 * \param type : output port type
1046 * \return an adaptated input port of type InputPyPort
1048 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
1051 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
1052 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1053 if(type->isAdaptable(inport->edGetType()))
1055 //the output data is convertible to inport type
1056 return new CppXml(inport);
1058 //non convertible type
1060 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1061 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1063 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1065 throw ConversionException(msg.str());
1068 //! Adapt a XML input port to a Neutral output port
1070 * \param inport : input port to adapt to Neutral type type
1071 * \param type : output port type
1072 * \return an adaptated input port of type Neutralxxxx
1074 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
1077 if(inport->edGetType()->isAdaptable(type))
1079 //the output data is convertible to inport type
1080 return new NeutralXml(inport);
1082 //non convertible type
1084 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
1085 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1086 throw ConversionException(msg.str());
1089 //! Adapt a XML input port to a Xml output port
1091 * \param inport : input port to adapt to Xml type type
1092 * \param type : output port type
1093 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1094 * \return an adaptated input port of type Xmlxxxx
1096 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
1097 TypeCode * type,bool init)
1100 return new ProxyPort(inport);
1102 if(inport->edGetType()->isAdaptable(type))
1103 return new ProxyPort(inport);
1106 msg << "Cannot connect Xml output port with type: " << type->id() ;
1107 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1109 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1111 throw ConversionException(msg.str());
1114 //! Adapt an Xml input port to an output port which implementation is given by impl
1116 * \param source : input port to adapt to implementation impl and type type
1117 * \param impl : output port implementation (C++, Python or Corba)
1118 * \param type : output port supported type
1119 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1120 * \return the adaptated port
1123 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1124 const std::string& impl,
1125 TypeCode * type,bool init)
1127 if(impl == CORBANode::IMPL_NAME)
1129 return adaptXmlToCorba(source,type);
1131 else if(impl == PythonNode::IMPL_NAME)
1133 return adaptXmlToPython(source,type);
1135 else if(impl == CppNode::IMPL_NAME)
1137 return adaptXmlToCpp(source,type);
1139 else if(impl == XmlNode::IMPL_NAME )
1141 return adaptXmlToXml(source,type,init);
1143 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1145 return adaptXmlToNeutral(source,type);
1150 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1151 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1152 throw ConversionException(msg.str());
1157 //! Adapt a CORBA input port to a CORBA output port
1159 * \param inport : input port to adapt to CORBA outport data type
1160 * \param type : outport data type
1161 * \return an adaptator port of type InputCORBAPort
1163 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1166 if(type->isA(inport->edGetType()))
1168 //types are compatible : no conversion
1169 //outport data type is more specific than inport required type
1170 //so the inport can be used safely
1171 return new ProxyPort(inport);
1173 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1175 //ouport data can be converted to inport data type
1176 return new CorbaCorba(inport);
1178 //outport data can not be converted
1180 msg << "Cannot connect Corba output port with type: " << type->id() ;
1181 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1183 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1185 throw ConversionException(msg.str());
1188 //! Adapt a CORBA input port to a Python output port
1190 * \param inport : input port to adapt to Python type type
1191 * \param type : outport data type
1192 * \return an adaptator port of type InputPyPort
1195 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1198 if(inport->edGetType()->kind() == Double)
1200 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1202 else if(inport->edGetType()->kind() == Int)
1204 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1206 else if(inport->edGetType()->kind() == String)
1208 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1210 else if(inport->edGetType()->kind() == Bool)
1212 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1214 else if(inport->edGetType()->kind() == Objref )
1216 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1218 return new PyCorbaObjref(inport);
1223 msg << "Cannot connect Python output port with type: " << type->id() ;
1224 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1225 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1226 throw ConversionException(msg.str());
1229 else if(inport->edGetType()->kind() == Sequence)
1231 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1233 return new PyCorbaSequence(inport);
1238 msg << "Cannot convert this sequence type " ;
1239 msg << __FILE__ << ":" <<__LINE__;
1240 throw ConversionException(msg.str());
1243 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1245 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1247 return new PyCorbaStruct(inport);
1252 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1253 msg << __FILE__ << ":" <<__LINE__;
1254 throw ConversionException(msg.str());
1257 // Adaptation not possible
1259 msg << "Cannot connect Python output port with type: " << type->id() ;
1260 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1262 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1264 throw ConversionException(msg.str());
1267 //! Adapt a CORBA input port to connect it to a XML output port
1269 * \param inport : input port to adapt to Xml type type
1270 * \param type : type supported by output port
1271 * \return an adaptator port of type InputXmlPort
1274 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1277 // BEWARE : using the generic check
1278 if(inport->edGetType()->isAdaptable(type))
1280 //output type is convertible to input type
1281 return new XmlCorba(inport);
1283 //output type is not convertible
1285 msg << "Cannot connect Xml output port with type: " << type->id() ;
1286 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1288 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1290 throw ConversionException(msg.str());
1293 //! Adapt a CORBA input port to a C++ output port
1295 * \param inport : input port to adapt to C++ type type
1296 * \param type : outport data type
1297 * \return an adaptator port of type InputCPPPort
1300 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1303 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1304 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1306 //output type is convertible to input type
1307 return new CppCorba(inport);
1309 //output type is not convertible
1311 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1312 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1314 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1316 throw ConversionException(msg.str());
1319 //! Adapt a CORBA input port to a neutral data
1321 * \param inport : InputPort to adapt to Neutral type type
1322 * \param type : outport data type
1323 * \return an adaptator port of type Neutralxxxx
1326 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1329 if(inport->edGetType()->kind() == Double)
1331 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1333 else if(inport->edGetType()->kind() == Int)
1335 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1337 else if(inport->edGetType()->kind() == String)
1339 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1341 else if(inport->edGetType()->kind() == Bool)
1343 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1345 else if(inport->edGetType()->kind() == Objref)
1347 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1349 else if(inport->edGetType()->kind() == Sequence)
1351 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1352 return new NeutralCorbaSequence(inport);
1356 msg << "Cannot convert this sequence type " ;
1357 msg << __FILE__ << ":" <<__LINE__;
1358 throw ConversionException(msg.str());
1361 else if(inport->edGetType()->kind() == Struct)
1363 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1366 // Adaptation not possible
1368 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1369 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1371 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1373 throw ConversionException(msg.str());
1376 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1378 * \param source : input port to adapt to implementation impl and type type
1379 * \param impl : output port implementation (C++, Python or Corba)
1380 * \param type : outport data type
1381 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1382 * \return an adaptator port which type depends on impl
1385 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1386 const std::string& impl,
1387 TypeCode * type,bool init)
1389 if(impl == CppNode::IMPL_NAME)
1391 return adaptCorbaToCpp(source,type);
1393 else if(impl == PythonNode::IMPL_NAME)
1395 return adaptCorbaToPython(source,type);
1397 else if(impl == CORBANode::IMPL_NAME)
1400 return adaptCorbaToCorba(source,type);
1402 return adaptCorbaToCorba(source,type);
1404 else if(impl == XmlNode::IMPL_NAME )
1406 return adaptCorbaToXml(source,type);
1408 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1410 return adaptCorbaToNeutral(source,type);
1415 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1416 msg << __FILE__ << ":" <<__LINE__;
1417 throw ConversionException(msg.str());
1421 //! Adapt a Python input port to a Python output port
1423 * No need to make conversion or cast.
1424 * Only check, it's possible.
1425 * \param inport : InputPort to adapt to Python type type
1426 * \param type : outport data type
1427 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1428 * \return an adaptator port of type InputPyPort
1431 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1432 TypeCode * type,bool init)
1435 return new PyInit(inport);
1437 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1439 //output data is convertible to input type
1440 //With python, no need to convert. Conversion will be done automatically
1441 //by the interpreter
1442 return new ProxyPort(inport);
1444 //output data is not convertible to input type
1446 msg << "Cannot connect Python output port with type: " << type->id() ;
1447 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1449 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1451 throw ConversionException(msg.str());
1454 //! Adapt a Python input port to a C++ output port
1456 * \param inport : InputPort to adapt to C++ type type
1457 * \param type : outport data type
1458 * \return an adaptator port of C++ type (InputCppPort)
1461 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1464 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1465 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1467 //output type is convertible to input type
1468 return new CppPy(inport);
1470 //output type is not convertible
1472 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1473 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1475 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1477 throw ConversionException(msg.str());
1480 //! Adapt a Python input port to a Neutral data port
1482 * \param inport : InputPort to adapt to Neutral type type
1483 * \param type : outport data type
1484 * \return an adaptator port of Neutral type (Neutralxxxx)
1487 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1490 if(inport->edGetType()->kind() == Double)
1492 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1494 else if(inport->edGetType()->kind() == Int)
1496 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1498 else if(inport->edGetType()->kind() == String)
1500 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1502 else if(inport->edGetType()->kind() == Bool)
1504 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1506 else if(inport->edGetType()->kind() == Objref)
1508 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1510 else if(inport->edGetType()->kind() == Sequence)
1512 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1513 return new NeutralPySequence(inport);
1517 msg << "Cannot convert this sequence type " ;
1518 msg << __FILE__ << ":" <<__LINE__;
1519 throw ConversionException(msg.str());
1522 else if(inport->edGetType()->kind() == Struct)
1524 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1527 // Adaptation not possible
1529 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1530 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1532 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1534 throw ConversionException(msg.str());
1537 //! Adapt a Python input port to a Corba output port
1539 * Always convert the data
1540 * \param inport : InputPort to adapt to Corba type type
1541 * \param type : outport data type
1542 * \return an adaptator port of Corba type (InputCorbaPort)
1545 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1548 if(inport->edGetType()->kind() == Double)
1550 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1552 else if(inport->edGetType()->kind() == Int)
1554 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1556 else if(inport->edGetType()->kind() == String)
1558 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1560 else if(inport->edGetType()->kind() == Bool)
1562 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1564 else if(inport->edGetType()->kind() == Objref)
1566 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1568 return new CorbaPyObjref(inport);
1573 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1574 msg << " " << __FILE__ << ":" <<__LINE__;
1575 throw ConversionException(msg.str());
1578 else if(inport->edGetType()->kind() == Sequence)
1580 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1582 return new CorbaPySequence(inport);
1587 msg << "Cannot convert this sequence type " ;
1588 msg << __FILE__ << ":" <<__LINE__;
1589 throw ConversionException(msg.str());
1592 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1594 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1596 return new CorbaPyStruct(inport);
1601 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1602 msg << " " << __FILE__ << ":" <<__LINE__;
1603 throw ConversionException(msg.str());
1606 // Adaptation not possible
1608 msg << "Cannot connect Corba output port with type: " << type->id() ;
1609 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1611 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1613 throw ConversionException(msg.str());
1616 //! Adapt a Python input port to a Xml output port
1618 * \param inport : input port to adapt to Xml type type
1619 * \param type : output port type
1620 * \return an input port of type InputXmlPort
1623 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1626 // BEWARE : using the generic check
1627 if(inport->edGetType()->isAdaptable(type))
1630 return new XmlPython(inport);
1632 //non convertible type
1634 msg << "Cannot connect Xml output port with type: " << type->id() ;
1635 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1637 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1639 throw ConversionException(msg.str());
1642 //! Adapt a Python input port to an output port with a given implementation
1644 * \param source : input port to adapt to implementation impl and type type
1645 * \param impl : output port implementation (C++, Python or Corba)
1646 * \param type : output port type
1647 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1648 * \return adaptated input port
1651 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1652 const std::string& impl,
1653 TypeCode * type,bool init)
1655 if(impl == CppNode::IMPL_NAME)
1657 return adaptPythonToCpp(source,type);
1659 else if(impl == PythonNode::IMPL_NAME)
1661 return adaptPythonToPython(source,type,init);
1663 else if(impl == CORBANode::IMPL_NAME)
1665 return adaptPythonToCorba(source,type);
1667 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1669 return adaptPythonToNeutral(source,type);
1671 else if(impl == XmlNode::IMPL_NAME)
1673 return adaptPythonToXml(source,type);
1678 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1679 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1680 throw ConversionException(msg.str());
1685 //! Adapt a C++ input port to connect it to a CORBA output port
1687 * \param inport : input port to adapt to CORBA type type
1688 * \param type : type supported by output port
1689 * \return an adaptator port of type InputCorbaPort
1692 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1695 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1696 if(isAdaptableCppCorba(type,inport->edGetType()))
1698 //output type is convertible to input type
1699 return new CorbaCpp(inport);
1701 //output type is not convertible
1703 msg << "Cannot connect Corba output port with type: " << type->id() ;
1704 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1706 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1708 throw ConversionException(msg.str());
1711 //! Adapt a C++ input port to a Python output port
1713 * \param inport : input port to adapt to Python type type
1714 * \param type : output port type
1715 * \return an adaptated input port of type InputPyPort
1717 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1720 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1721 if(isAdaptableCppPyObject(type,inport->edGetType()))
1723 //output type is convertible to input type
1724 return new PyCpp(inport);
1726 //output type is not convertible
1728 msg << "Cannot connect Python output port with type: " << type->id() ;
1729 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1731 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1733 throw ConversionException(msg.str());
1736 //! Adapt a C++ input port to a C++ output port
1738 * \param inport : input port to adapt to C++ type type
1739 * \param type : output port type
1740 * \return an adaptated input port of type InputPyPort
1742 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1745 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1746 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1747 if(type->isAdaptable(inport->edGetType()))
1749 //the output data is convertible to inport type
1750 return new CppCpp(inport);
1752 //non convertible type
1754 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1755 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1757 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1759 throw ConversionException(msg.str());
1762 //! Adapt a C++ input port to a Neutral output port
1764 * \param inport : input port to adapt to C++ type type
1765 * \param type : output port type
1766 * \return an adaptated input port of type InputPyPort
1768 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1771 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1772 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1773 if(type->isAdaptable(inport->edGetType()))
1775 //the output data is convertible to inport type
1776 return new NeutralCpp(inport);
1778 //non convertible type
1780 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1781 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1783 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1785 throw ConversionException(msg.str());
1788 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1791 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1792 if(isAdaptableCppXml(type,inport->edGetType()))
1795 return new XmlCpp(inport);
1797 //non convertible type
1799 msg << "Cannot connect Xml output port with type: " << type->id() ;
1800 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1802 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1804 throw ConversionException(msg.str());
1807 //! Adapt a C++ input port to connect it to an output port with a given implementation
1809 * \param source : input port to adapt to implementation impl and type type
1810 * \param impl : output port implementation (C++, Python or Corba)
1811 * \param type : output port supported type
1812 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1813 * \return the adaptated port
1816 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1817 const std::string& impl,
1818 TypeCode * type,bool init)
1820 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1821 if(impl == CORBANode::IMPL_NAME)
1823 return adaptCppToCorba(source,type);
1825 else if(impl == PythonNode::IMPL_NAME)
1827 return adaptCppToPython(source,type);
1829 else if(impl == XmlNode::IMPL_NAME)
1831 return adaptCppToXml(source,type);
1833 else if(impl == CppNode::IMPL_NAME)
1835 return adaptCppToCpp(source, type);
1837 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1839 return adaptCppToNeutral(source, type);
1844 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1845 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1846 throw ConversionException(msg.str());
1850 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1851 // const InputPort* inputPort)
1853 // bool result=true;
1857 CORBA::ORB_ptr RuntimeSALOME::getOrb() const
1862 PyObject * RuntimeSALOME::getPyOrb() const
1867 PyObject * RuntimeSALOME::getBuiltins() const
1872 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory() const
1877 PyObject * RuntimeSALOME::get_omnipy()
1882 omniORBpyAPI* RuntimeSALOME::getApi()
1887 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1890 return (void *)convertNeutralPyObject(type,data);
1894 return (void *)Py_None;
1898 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1903 // The call to PyGILState_Ensure was moved here because there was also
1904 // a crash when calling convertNeutralPyObject with a sequence of pyobj.
1905 // see also the comment below.
1906 PyGILState_STATE gstate = PyGILState_Ensure();
1907 ob=convertNeutralPyObject(type,data);
1908 std::string s=convertPyObjectToString(ob);
1910 // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1911 // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1912 // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1913 // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1914 // feel free to change this code.
1915 //PyGILState_STATE gstate = PyGILState_Ensure();
1917 PyGILState_Release(gstate);
1926 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1928 return YACS::ENGINE::convertPyObjectToString(ob);
1931 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1936 PyGILState_STATE gstate = PyGILState_Ensure();
1937 mainmod = PyImport_AddModule("__main__");
1938 globals = PyModule_GetDict(mainmod);
1939 PyObject* d = PyDict_New();
1940 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1941 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1947 PyObject* new_stderr = newPyStdOut(error);
1948 PySys_SetObject((char *)"stderr", new_stderr);
1950 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1951 Py_DECREF(new_stderr);
1952 PyGILState_Release(gstate);
1953 throw Exception(error);
1955 PyGILState_Release(gstate);