1 // Copyright (C) 2006-2016 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)
296 PySys_SetArgv(argc, argv);
301 char defaultName[] = "SALOME_YACS_RUNTIME";
302 pyArgv[0] = defaultName;
303 PySys_SetArgv(pyArgc, pyArgv);
305 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
306 PyEval_SaveThread(); /* Release the thread state */
307 //here we do not have the Global Interpreter Lock
310 PyObject *mainmod,*pyapi,*res ;
312 PyGILState_STATE gstate;
313 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
315 mainmod = PyImport_AddModule("__main__");
316 globals = PyModule_GetDict(mainmod);
317 /* globals is a borrowed reference */
319 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
321 PyObject *bimod = PyImport_ImportModule("__builtin__");
322 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
323 Py_FatalError("can't add __builtins__ to __main__");
327 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
333 _omnipy = PyImport_ImportModule((char*)"_omnipy");
337 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
340 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
345 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
348 res=PyRun_String("\n"
349 "from math import *\n"
351 "sys.path.insert(0,'.')\n"
352 "from omniORB import CORBA\n"
353 "from omniORB import any\n"
354 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
355 "#print sys.getrefcount(orb)\n"
361 Py_file_input,globals,globals );
369 _pyorb = PyDict_GetItemString(globals,"orb");
370 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
373 pyany = PyDict_GetItemString(globals,"any");
374 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
377 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
381 PyGILState_Release(gstate); // Release the Global Interpreter Lock
385 // initialize the catalogLoaderFactory map with the session one
386 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
390 void RuntimeSALOME::fini()
394 PyGILState_STATE gstate = PyGILState_Ensure();
396 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
398 PyObject *mainmod, *globals;
399 mainmod = PyImport_AddModule("__main__");
400 globals = PyModule_GetDict(mainmod);
404 res=PyRun_String("orb.destroy()\n"
406 Py_file_input,globals,globals );
412 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
413 delete nodeMap["PyFunction"];
414 delete nodeMap["PyScript"];
415 delete nodeMap["SalomePythonNode"];
416 nodeMap.erase("PyFunction");
417 nodeMap.erase("PyScript");
418 nodeMap.erase("SalomePythonNode");
422 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
430 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
437 std::vector< std::pair<std::string,int> > RuntimeSALOME::getCatalogOfComputeNodes() const
439 CORBA::ORB_ptr orb(getOrb());
440 SALOME_NamingService namingService;
443 namingService.init_orb(orb);
445 catch(SALOME_Exception& e)
447 throw Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Unable to contact the SALOME Naming Service");
449 CORBA::Object_var obj(namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS));
450 if(CORBA::is_nil(obj))
451 throw Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Unable to access to the resource manager !");
452 Engines::ResourcesManager_var resManager(Engines::ResourcesManager::_narrow(obj));
453 if(CORBA::is_nil(resManager))
454 throw Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Internal error ! The entry attached to the res manager in NS does not have right type !");
455 std::vector< std::pair<std::string,int> > ret;
457 Engines::ResourceList *rl(0);
458 Engines::IntegerList *il(0);
459 resManager->ListAllAvailableResources(rl,il);
460 int sz(rl->length());
462 throw Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Internal error ! Invalid size !");
464 for(int i=0;i<sz;i++)
466 std::string s((*rl)[i]);
467 ret[i]=std::pair<std::string,int>(s,(*il)[i]);
475 std::string RuntimeSALOME::getVersion() const
477 #ifdef YACS_DEVELOPMENT
478 return CORBA::string_dup(YACS_VERSION_STR"dev");
480 return CORBA::string_dup(YACS_VERSION_STR);
484 Proc* RuntimeSALOME::createProc(const std::string& name)
486 return new SalomeProc(name);
489 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
490 std::list<TypeCodeObjref *> ltc)
493 if(id == "") myName = "IDL:" + name + ":1.0";
495 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
498 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
499 const std::string& name,
502 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
505 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
508 if(id == "") myName = "IDL:" + name + ":1.0";
510 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
513 Bloc* RuntimeSALOME::createBloc(const std::string& name)
515 return new Bloc(name);
518 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
520 return new WhileLoop(name);
523 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
525 return new ForLoop(name);
528 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
529 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
531 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
532 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
533 ol->edGetNbOfBranchesPort()->edInit(1);
537 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
542 node = new PresetNode(name);
545 else if(kind == "study" )
547 return new StudyInNode(name);
549 std::string msg="DataNode kind ("+kind+") unknown";
550 throw Exception(msg);
553 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
557 return new OutNode(name);
559 else if(kind == "study" )
561 return new StudyOutNode(name);
564 std::string msg="OutDataNode kind ("+kind+") unknown";
565 throw Exception(msg);
568 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
570 InlineFuncNode* node;
571 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
573 node = new PyFuncNode(name);
576 if(kind == DistributedPythonNode::KIND)
577 return new DistributedPythonNode(name);
578 std::string msg="FuncNode kind ("+kind+") unknown";
579 throw Exception(msg);
582 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
585 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
587 node = new PythonNode(name);
590 std::string msg="ScriptNode kind ("+kind+") unknown";
591 throw Exception(msg);
594 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
597 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
599 node = new CORBANode(name);
602 else if(kind == XmlNode::KIND)
604 node = new XmlNode(name);
607 std::string msg="RefNode kind ("+kind+") unknown";
608 throw Exception(msg);
611 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
614 if(kind == "" || kind == SalomeNode::KIND )
616 node=new SalomeNode(name);
619 else if (kind == CppNode::KIND)
621 node = new CppNode(name);
624 std::string msg="CompoNode kind ("+kind+") unknown";
625 throw Exception(msg);
628 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
630 if(kind == "" || kind == SalomeNode::KIND )
631 return new SalomePythonNode(name);
632 std::string msg="CompoNode kind ("+kind+") unknown";
633 throw Exception(msg);
636 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
637 const std::string& kind)
639 ComponentInstance* compo;
640 if(kind == "" || kind == SalomeComponent::KIND)
641 return new SalomeComponent(name);
642 else if(kind == CORBAComponent::KIND)
643 return new CORBAComponent(name);
644 else if(kind == SalomePythonComponent::KIND)
645 return new SalomePythonComponent(name);
646 else if (kind == CppComponent::KIND)
647 return new CppComponent(name);
648 else if (kind == SalomeHPComponent::KIND)
649 return new SalomeHPComponent(name);
650 std::string msg="Component Instance kind ("+kind+") unknown";
651 throw Exception(msg);
654 Container *RuntimeSALOME::createContainer(const std::string& kind)
656 if(kind == "" || kind == SalomeContainer::KIND)
657 return new SalomeContainer;
658 if(kind==SalomeHPContainer::KIND)
659 return new SalomeHPContainer;
660 else if (kind == CppContainer::KIND)
661 return new CppContainer;
662 std::string msg="Container kind ("+kind+") unknown";
663 throw Exception(msg);
666 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
667 const std::string& impl,
671 if(impl == CppNode::IMPL_NAME)
673 return new InputCppPort(name, node, type);
675 else if(impl == PythonNode::IMPL_NAME)
677 return new InputPyPort(name, node, type);
679 else if(impl == CORBANode::IMPL_NAME)
681 return new InputCorbaPort(name, node, type);
683 else if(impl == XmlNode::IMPL_NAME)
685 return new InputXmlPort(name, node, type);
690 msg << "Cannot create " << impl << " InputPort" ;
691 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
692 throw Exception(msg.str());
696 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
697 const std::string& impl,
701 if(impl == CppNode::IMPL_NAME)
703 return new OutputCppPort(name, node, type);
705 else if(impl == PythonNode::IMPL_NAME)
707 return new OutputPyPort(name, node, type);
709 else if(impl == CORBANode::IMPL_NAME)
711 return new OutputCorbaPort(name, node, type);
713 else if(impl == XmlNode::IMPL_NAME)
715 return new OutputXmlPort(name, node, type);
720 msg << "Cannot create " << impl << " OutputPort" ;
721 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
722 throw Exception(msg.str());
726 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
727 Node *node,TypeCode *type)
729 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
730 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
732 return new InputCalStreamPort(name,node,type);
736 return new InputDataStreamPort(name,node,type);
740 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
741 Node *node,TypeCode *type)
743 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
744 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
746 return new OutputCalStreamPort(name,node,type);
750 return new OutputDataStreamPort(name,node,type);
754 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
756 * \param source : InputPort to be adapted
757 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
758 * \param type : data type provided by the InputPort
759 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
761 * \return : adapted InputPort
763 InputPort* RuntimeSALOME::adapt(InputPort* source,
764 const std::string& impl,
765 TypeCode * type,bool init) throw (ConversionException)
767 string imp_source=source->getNode()->getImplementation();
768 if(imp_source == PythonNode::IMPL_NAME)
770 return adapt((InputPyPort*)source,impl,type,init);
772 else if(imp_source == CppNode::IMPL_NAME)
774 return adapt((InputCppPort*)source,impl,type,init);
776 else if(imp_source == CORBANode::IMPL_NAME)
778 return adapt((InputCorbaPort*)source,impl,type,init);
780 else if(imp_source == XmlNode::IMPL_NAME)
782 return adapt((InputXmlPort*)source,impl,type,init);
784 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
786 return adaptNeutral(source,impl,type,init);
791 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
792 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
793 throw ConversionException(msg.str());
797 //! Adapter function for InPropertyPort
799 * \param source : InPropertyPort to be adapted
800 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
801 * \param type : data type provided by the InPropertyPort
802 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
804 * \return : adapted InputPort
806 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
807 const std::string& impl,
808 TypeCode * type,bool init) throw (ConversionException)
810 return adaptNeutral((InputPort *)source,impl,type,init);
813 //! Adapt a Neutral input port to a Corba output port
815 * \param inport : Neutral input port to adapt to Corba type type
816 * \param type : output port type
817 * \return an adaptated input port of type InputCorbaPort
819 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
820 TypeCode * type) throw (ConversionException)
822 // BEWARE : using the generic check
823 if(inport->edGetType()->isAdaptable(type))
825 //the output data is convertible to inport type
826 return new CorbaNeutral(inport);
828 //non convertible type
830 msg << "Cannot connect Corba output port with type: " << type->id() ;
831 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
833 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
835 throw ConversionException(msg.str());
838 //! Adapt a Neutral input port to a Python output port
840 * \param inport : input port to adapt to Python type type
841 * \param type : output port type
842 * \return an adaptated input port of type InputPyPort
844 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
845 TypeCode * type) throw (ConversionException)
847 // BEWARE : using the generic check
848 if(inport->edGetType()->isAdaptable(type))
851 return new PyNeutral(inport);
853 //last chance : an py output that is seq[objref] can be connected to a neutral input objref (P13268)
854 else if(type->kind()==Sequence && type->contentType()->kind()==Objref && inport->edGetType()->kind()==Objref)
856 return new PyNeutral(inport);
858 //non convertible type
860 msg << "Cannot connect Python output port with type: " << type->id() ;
861 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
863 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
865 throw ConversionException(msg.str());
868 //! Adapt a Neutral input port to a Xml output port
870 * \param inport : input port to adapt to Xml type type
871 * \param type : output port type
872 * \return an input port of type InputXmlPort
874 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
875 TypeCode * type) throw (ConversionException)
877 // BEWARE : using the generic check
878 if(inport->edGetType()->isAdaptable(type))
881 return new XmlNeutral(inport);
883 //non convertible type
885 msg << "Cannot connect Xml output port with type: " << type->id() ;
886 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
888 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
890 throw ConversionException(msg.str());
893 //! Adapt a Neutral input port to a C++ output port
895 * \param inport : input port to adapt to C++ type type
896 * \param type : output port type
897 * \return an input port of type InputCppPort
899 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
900 TypeCode * type) throw (ConversionException)
902 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
903 if(isAdaptableNeutralCpp(type,inport->edGetType()))
906 return new CppNeutral(inport);
908 //non convertible type
910 msg << "Cannot connect Cpp output port with type: " << type->id() ;
911 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
913 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
915 throw ConversionException(msg.str());
918 //! Adapt a Neutral input port to connect it to an output port with a given implementation
920 * \param source : Neutral input port to adapt to implementation impl and type type
921 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
922 * \param type : output port supported type
923 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
924 * \return the adaptated port
926 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
927 const std::string& impl,
928 TypeCode * type,bool init) throw (ConversionException)
930 if(impl == CppNode::IMPL_NAME)
932 return adaptNeutralToCpp(source,type);
934 else if(impl == PythonNode::IMPL_NAME)
936 return adaptNeutralToPython(source,type);
938 else if(impl == CORBANode::IMPL_NAME)
940 return adaptNeutralToCorba(source,type);
942 else if(impl == XmlNode::IMPL_NAME )
944 return adaptNeutralToXml(source,type);
946 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
949 return new NeutralInit(source);
951 return new ProxyPort(source);
954 msg << "Cannot connect InputPort : unknown implementation " << impl;
955 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
956 throw ConversionException(msg.str());
959 //! Adapt a XML input port to connect it to a CORBA output port
961 * \param inport : input port to adapt to CORBA type type
962 * \param type : type supported by output port
963 * \return an adaptator port of type InputCorbaPort
966 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
967 TypeCode * type) throw (ConversionException)
969 if(isAdaptableXmlCorba(type,inport->edGetType()))
971 //output type is convertible to input type
972 return new CorbaXml(inport);
974 //output type is not convertible
976 msg << "Cannot connect Corba output port with type: " << type->id() ;
977 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
979 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
981 throw ConversionException(msg.str());
984 //! Adapt a XML input port to a Python output port
986 * \param inport : input port to adapt to Python type type
987 * \param type : output port type
988 * \return an adaptated input port of type InputPyPort
990 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
991 TypeCode * type) throw (ConversionException)
993 if(inport->edGetType()->isAdaptable(type))
995 //the output data is convertible to inport type
996 return new PyXml(inport);
998 //non convertible type
1000 msg << "Cannot connect Python output port with type: " << type->id() ;
1001 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1003 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1005 throw ConversionException(msg.str());
1008 //! Adapt a XML input port to a C++ output port
1010 * \param inport : input port to adapt to C++ type type
1011 * \param type : output port type
1012 * \return an adaptated input port of type InputPyPort
1014 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
1015 TypeCode * type) throw (ConversionException)
1017 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
1018 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1019 if(type->isAdaptable(inport->edGetType()))
1021 //the output data is convertible to inport type
1022 return new CppXml(inport);
1024 //non convertible type
1026 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1027 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1029 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1031 throw ConversionException(msg.str());
1034 //! Adapt a XML input port to a Neutral output port
1036 * \param inport : input port to adapt to Neutral type type
1037 * \param type : output port type
1038 * \return an adaptated input port of type Neutralxxxx
1040 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
1041 TypeCode * type) throw (ConversionException)
1043 if(inport->edGetType()->isAdaptable(type))
1045 //the output data is convertible to inport type
1046 return new NeutralXml(inport);
1048 //non convertible type
1050 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
1051 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1052 throw ConversionException(msg.str());
1055 //! Adapt a XML input port to a Xml output port
1057 * \param inport : input port to adapt to Xml type type
1058 * \param type : output port type
1059 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1060 * \return an adaptated input port of type Xmlxxxx
1062 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
1063 TypeCode * type,bool init) throw (ConversionException)
1066 return new ProxyPort(inport);
1068 if(inport->edGetType()->isAdaptable(type))
1069 return new ProxyPort(inport);
1072 msg << "Cannot connect Xml output port with type: " << type->id() ;
1073 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1075 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1077 throw ConversionException(msg.str());
1080 //! Adapt an Xml input port to an output port which implementation is given by impl
1082 * \param source : input port to adapt to implementation impl and type type
1083 * \param impl : output port implementation (C++, Python or Corba)
1084 * \param type : output port supported type
1085 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1086 * \return the adaptated port
1089 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1090 const std::string& impl,
1091 TypeCode * type,bool init) throw (ConversionException)
1093 if(impl == CORBANode::IMPL_NAME)
1095 return adaptXmlToCorba(source,type);
1097 else if(impl == PythonNode::IMPL_NAME)
1099 return adaptXmlToPython(source,type);
1101 else if(impl == CppNode::IMPL_NAME)
1103 return adaptXmlToCpp(source,type);
1105 else if(impl == XmlNode::IMPL_NAME )
1107 return adaptXmlToXml(source,type,init);
1109 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1111 return adaptXmlToNeutral(source,type);
1116 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1117 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1118 throw ConversionException(msg.str());
1123 //! Adapt a CORBA input port to a CORBA output port
1125 * \param inport : input port to adapt to CORBA outport data type
1126 * \param type : outport data type
1127 * \return an adaptator port of type InputCORBAPort
1129 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1130 TypeCode * type) throw (ConversionException)
1132 if(type->isA(inport->edGetType()))
1134 //types are compatible : no conversion
1135 //outport data type is more specific than inport required type
1136 //so the inport can be used safely
1137 return new ProxyPort(inport);
1139 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1141 //ouport data can be converted to inport data type
1142 return new CorbaCorba(inport);
1144 //outport data can not be converted
1146 msg << "Cannot connect Corba output port with type: " << type->id() ;
1147 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1149 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1151 throw ConversionException(msg.str());
1154 //! Adapt a CORBA input port to a Python output port
1156 * \param inport : input port to adapt to Python type type
1157 * \param type : outport data type
1158 * \return an adaptator port of type InputPyPort
1161 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1162 TypeCode * type) throw (ConversionException)
1164 if(inport->edGetType()->kind() == Double)
1166 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1168 else if(inport->edGetType()->kind() == Int)
1170 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1172 else if(inport->edGetType()->kind() == String)
1174 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1176 else if(inport->edGetType()->kind() == Bool)
1178 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1180 else if(inport->edGetType()->kind() == Objref )
1182 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1184 return new PyCorbaObjref(inport);
1189 msg << "Cannot connect Python output port with type: " << type->id() ;
1190 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1191 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1192 throw ConversionException(msg.str());
1195 else if(inport->edGetType()->kind() == Sequence)
1197 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1199 return new PyCorbaSequence(inport);
1204 msg << "Cannot convert this sequence type " ;
1205 msg << __FILE__ << ":" <<__LINE__;
1206 throw ConversionException(msg.str());
1209 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1211 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1213 return new PyCorbaStruct(inport);
1218 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1219 msg << __FILE__ << ":" <<__LINE__;
1220 throw ConversionException(msg.str());
1223 // Adaptation not possible
1225 msg << "Cannot connect Python output port with type: " << type->id() ;
1226 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1228 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1230 throw ConversionException(msg.str());
1233 //! Adapt a CORBA input port to connect it to a XML output port
1235 * \param inport : input port to adapt to Xml type type
1236 * \param type : type supported by output port
1237 * \return an adaptator port of type InputXmlPort
1240 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1241 TypeCode * type) throw (ConversionException)
1243 // BEWARE : using the generic check
1244 if(inport->edGetType()->isAdaptable(type))
1246 //output type is convertible to input type
1247 return new XmlCorba(inport);
1249 //output type is not convertible
1251 msg << "Cannot connect Xml output port with type: " << type->id() ;
1252 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1254 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1256 throw ConversionException(msg.str());
1259 //! Adapt a CORBA input port to a C++ output port
1261 * \param inport : input port to adapt to C++ type type
1262 * \param type : outport data type
1263 * \return an adaptator port of type InputCPPPort
1266 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1267 TypeCode * type) throw (ConversionException)
1269 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1270 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1272 //output type is convertible to input type
1273 return new CppCorba(inport);
1275 //output type is not convertible
1277 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1278 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1280 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1282 throw ConversionException(msg.str());
1285 //! Adapt a CORBA input port to a neutral data
1287 * \param inport : InputPort to adapt to Neutral type type
1288 * \param type : outport data type
1289 * \return an adaptator port of type Neutralxxxx
1292 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1293 TypeCode * type) throw (ConversionException)
1295 if(inport->edGetType()->kind() == Double)
1297 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1299 else if(inport->edGetType()->kind() == Int)
1301 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1303 else if(inport->edGetType()->kind() == String)
1305 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1307 else if(inport->edGetType()->kind() == Bool)
1309 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1311 else if(inport->edGetType()->kind() == Objref)
1313 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1315 else if(inport->edGetType()->kind() == Sequence)
1317 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1318 return new NeutralCorbaSequence(inport);
1322 msg << "Cannot convert this sequence type " ;
1323 msg << __FILE__ << ":" <<__LINE__;
1324 throw ConversionException(msg.str());
1327 else if(inport->edGetType()->kind() == Struct)
1329 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1332 // Adaptation not possible
1334 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1335 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1337 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1339 throw ConversionException(msg.str());
1342 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1344 * \param source : input port to adapt to implementation impl and type type
1345 * \param impl : output port implementation (C++, Python or Corba)
1346 * \param type : outport data type
1347 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1348 * \return an adaptator port which type depends on impl
1351 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1352 const std::string& impl,
1353 TypeCode * type,bool init) throw (ConversionException)
1355 if(impl == CppNode::IMPL_NAME)
1357 return adaptCorbaToCpp(source,type);
1359 else if(impl == PythonNode::IMPL_NAME)
1361 return adaptCorbaToPython(source,type);
1363 else if(impl == CORBANode::IMPL_NAME)
1366 return adaptCorbaToCorba(source,type);
1368 return adaptCorbaToCorba(source,type);
1370 else if(impl == XmlNode::IMPL_NAME )
1372 return adaptCorbaToXml(source,type);
1374 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1376 return adaptCorbaToNeutral(source,type);
1381 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1382 msg << __FILE__ << ":" <<__LINE__;
1383 throw ConversionException(msg.str());
1387 //! Adapt a Python input port to a Python output port
1389 * No need to make conversion or cast.
1390 * Only check, it's possible.
1391 * \param inport : InputPort to adapt to Python type type
1392 * \param type : outport data type
1393 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1394 * \return an adaptator port of type InputPyPort
1397 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1398 TypeCode * type,bool init) throw (ConversionException)
1401 return new PyInit(inport);
1403 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1405 //output data is convertible to input type
1406 //With python, no need to convert. Conversion will be done automatically
1407 //by the interpreter
1408 return new ProxyPort(inport);
1410 //output data is not convertible to input type
1412 msg << "Cannot connect Python output port with type: " << type->id() ;
1413 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1415 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1417 throw ConversionException(msg.str());
1420 //! Adapt a Python input port to a C++ output port
1422 * \param inport : InputPort to adapt to C++ type type
1423 * \param type : outport data type
1424 * \return an adaptator port of C++ type (InputCppPort)
1427 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1428 TypeCode * type) throw (ConversionException)
1430 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1431 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1433 //output type is convertible to input type
1434 return new CppPy(inport);
1436 //output type is not convertible
1438 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1439 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1441 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1443 throw ConversionException(msg.str());
1446 //! Adapt a Python input port to a Neutral data port
1448 * \param inport : InputPort to adapt to Neutral type type
1449 * \param type : outport data type
1450 * \return an adaptator port of Neutral type (Neutralxxxx)
1453 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1454 TypeCode * type) throw (ConversionException)
1456 if(inport->edGetType()->kind() == Double)
1458 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1460 else if(inport->edGetType()->kind() == Int)
1462 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1464 else if(inport->edGetType()->kind() == String)
1466 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1468 else if(inport->edGetType()->kind() == Bool)
1470 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1472 else if(inport->edGetType()->kind() == Objref)
1474 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1476 else if(inport->edGetType()->kind() == Sequence)
1478 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1479 return new NeutralPySequence(inport);
1483 msg << "Cannot convert this sequence type " ;
1484 msg << __FILE__ << ":" <<__LINE__;
1485 throw ConversionException(msg.str());
1488 else if(inport->edGetType()->kind() == Struct)
1490 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1493 // Adaptation not possible
1495 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1496 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1498 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1500 throw ConversionException(msg.str());
1503 //! Adapt a Python input port to a Corba output port
1505 * Always convert the data
1506 * \param inport : InputPort to adapt to Corba type type
1507 * \param type : outport data type
1508 * \return an adaptator port of Corba type (InputCorbaPort)
1511 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1512 TypeCode * type) throw (ConversionException)
1514 if(inport->edGetType()->kind() == Double)
1516 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1518 else if(inport->edGetType()->kind() == Int)
1520 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1522 else if(inport->edGetType()->kind() == String)
1524 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1526 else if(inport->edGetType()->kind() == Bool)
1528 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1530 else if(inport->edGetType()->kind() == Objref)
1532 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1534 return new CorbaPyObjref(inport);
1539 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1540 msg << " " << __FILE__ << ":" <<__LINE__;
1541 throw ConversionException(msg.str());
1544 else if(inport->edGetType()->kind() == Sequence)
1546 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1548 return new CorbaPySequence(inport);
1553 msg << "Cannot convert this sequence type " ;
1554 msg << __FILE__ << ":" <<__LINE__;
1555 throw ConversionException(msg.str());
1558 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1560 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1562 return new CorbaPyStruct(inport);
1567 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1568 msg << " " << __FILE__ << ":" <<__LINE__;
1569 throw ConversionException(msg.str());
1572 // Adaptation not possible
1574 msg << "Cannot connect Corba output port with type: " << type->id() ;
1575 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1577 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1579 throw ConversionException(msg.str());
1582 //! Adapt a Python input port to a Xml output port
1584 * \param inport : input port to adapt to Xml type type
1585 * \param type : output port type
1586 * \return an input port of type InputXmlPort
1589 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1590 TypeCode * type) throw (ConversionException)
1592 // BEWARE : using the generic check
1593 if(inport->edGetType()->isAdaptable(type))
1596 return new XmlPython(inport);
1598 //non convertible type
1600 msg << "Cannot connect Xml output port with type: " << type->id() ;
1601 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1603 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1605 throw ConversionException(msg.str());
1608 //! Adapt a Python input port to an output port with a given implementation
1610 * \param source : input port to adapt to implementation impl and type type
1611 * \param impl : output port implementation (C++, Python or Corba)
1612 * \param type : output port type
1613 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1614 * \return adaptated input port
1617 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1618 const std::string& impl,
1619 TypeCode * type,bool init) throw (ConversionException)
1621 if(impl == CppNode::IMPL_NAME)
1623 return adaptPythonToCpp(source,type);
1625 else if(impl == PythonNode::IMPL_NAME)
1627 return adaptPythonToPython(source,type,init);
1629 else if(impl == CORBANode::IMPL_NAME)
1631 return adaptPythonToCorba(source,type);
1633 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1635 return adaptPythonToNeutral(source,type);
1637 else if(impl == XmlNode::IMPL_NAME)
1639 return adaptPythonToXml(source,type);
1644 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1645 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1646 throw ConversionException(msg.str());
1651 //! Adapt a C++ input port to connect it to a CORBA output port
1653 * \param inport : input port to adapt to CORBA type type
1654 * \param type : type supported by output port
1655 * \return an adaptator port of type InputCorbaPort
1658 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1659 TypeCode * type) throw (ConversionException)
1661 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1662 if(isAdaptableCppCorba(type,inport->edGetType()))
1664 //output type is convertible to input type
1665 return new CorbaCpp(inport);
1667 //output type is not convertible
1669 msg << "Cannot connect Corba output port with type: " << type->id() ;
1670 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1672 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1674 throw ConversionException(msg.str());
1677 //! Adapt a C++ input port to a Python output port
1679 * \param inport : input port to adapt to Python type type
1680 * \param type : output port type
1681 * \return an adaptated input port of type InputPyPort
1683 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1684 TypeCode * type) throw (ConversionException)
1686 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1687 if(isAdaptableCppPyObject(type,inport->edGetType()))
1689 //output type is convertible to input type
1690 return new PyCpp(inport);
1692 //output type is not convertible
1694 msg << "Cannot connect Python output port with type: " << type->id() ;
1695 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1697 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1699 throw ConversionException(msg.str());
1702 //! Adapt a C++ input port to a C++ output port
1704 * \param inport : input port to adapt to C++ type type
1705 * \param type : output port type
1706 * \return an adaptated input port of type InputPyPort
1708 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1709 TypeCode * type) throw (ConversionException)
1711 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1712 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1713 if(type->isAdaptable(inport->edGetType()))
1715 //the output data is convertible to inport type
1716 return new CppCpp(inport);
1718 //non convertible type
1720 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1721 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1723 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1725 throw ConversionException(msg.str());
1728 //! Adapt a C++ input port to a Neutral output port
1730 * \param inport : input port to adapt to C++ type type
1731 * \param type : output port type
1732 * \return an adaptated input port of type InputPyPort
1734 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1735 TypeCode * type) throw (ConversionException)
1737 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1738 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1739 if(type->isAdaptable(inport->edGetType()))
1741 //the output data is convertible to inport type
1742 return new NeutralCpp(inport);
1744 //non convertible type
1746 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1747 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1749 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1751 throw ConversionException(msg.str());
1754 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1755 TypeCode * type) throw (ConversionException)
1757 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1758 if(isAdaptableCppXml(type,inport->edGetType()))
1761 return new XmlCpp(inport);
1763 //non convertible type
1765 msg << "Cannot connect Xml output port with type: " << type->id() ;
1766 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1768 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1770 throw ConversionException(msg.str());
1773 //! Adapt a C++ input port to connect it to an output port with a given implementation
1775 * \param source : input port to adapt to implementation impl and type type
1776 * \param impl : output port implementation (C++, Python or Corba)
1777 * \param type : output port supported type
1778 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1779 * \return the adaptated port
1782 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1783 const std::string& impl,
1784 TypeCode * type,bool init) throw (ConversionException)
1786 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1787 if(impl == CORBANode::IMPL_NAME)
1789 return adaptCppToCorba(source,type);
1791 else if(impl == PythonNode::IMPL_NAME)
1793 return adaptCppToPython(source,type);
1795 else if(impl == XmlNode::IMPL_NAME)
1797 return adaptCppToXml(source,type);
1799 else if(impl == CppNode::IMPL_NAME)
1801 return adaptCppToCpp(source, type);
1803 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1805 return adaptCppToNeutral(source, type);
1810 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1811 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1812 throw ConversionException(msg.str());
1816 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1817 // const InputPort* inputPort)
1819 // bool result=true;
1823 CORBA::ORB_ptr RuntimeSALOME::getOrb() const
1828 PyObject * RuntimeSALOME::getPyOrb() const
1833 PyObject * RuntimeSALOME::getBuiltins() const
1838 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory() const
1843 PyObject * RuntimeSALOME::get_omnipy()
1848 omniORBpyAPI* RuntimeSALOME::getApi()
1853 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1856 return (void *)convertNeutralPyObject(type,data);
1860 return (void *)Py_None;
1864 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1869 // The call to PyGILState_Ensure was moved here because there was also
1870 // a crash when calling convertNeutralPyObject with a sequence of pyobj.
1871 // see also the comment below.
1872 PyGILState_STATE gstate = PyGILState_Ensure();
1873 ob=convertNeutralPyObject(type,data);
1874 std::string s=convertPyObjectToString(ob);
1876 // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1877 // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1878 // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1879 // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1880 // feel free to change this code.
1881 //PyGILState_STATE gstate = PyGILState_Ensure();
1883 PyGILState_Release(gstate);
1892 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1894 return YACS::ENGINE::convertPyObjectToString(ob);
1897 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1902 PyGILState_STATE gstate = PyGILState_Ensure();
1903 mainmod = PyImport_AddModule("__main__");
1904 globals = PyModule_GetDict(mainmod);
1905 PyObject* d = PyDict_New();
1906 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1907 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1913 PyObject* new_stderr = newPyStdOut(error);
1914 PySys_SetObject((char *)"stderr", new_stderr);
1916 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1917 Py_DECREF(new_stderr);
1918 PyGILState_Release(gstate);
1919 throw Exception(error);
1921 PyGILState_Release(gstate);