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"
117 #include <libxml/parser.h>
118 #include <omniORB4/CORBA.h>
124 #include "YacsTrace.hxx"
127 using namespace YACS::ENGINE;
129 void RuntimeSALOME::setRuntime(long flags, int argc, char* argv[]) // singleton creation (not thread safe!)
131 if (! Runtime::_singleton)
133 RuntimeSALOME* r=new RuntimeSALOME(flags, argc, argv);
134 Runtime::_singleton = r;
137 DEBTRACE("RuntimeSALOME::setRuntime() done !");
140 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
142 YASSERT(Runtime::_singleton);
143 return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
147 * Singleton creation, initialize converter map
150 RuntimeSALOME::RuntimeSALOME()
155 void RuntimeSALOME::initBuiltins()
157 //Fill the builtin catalog with nodes specific to the runtime
158 std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
159 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
160 std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
161 std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
162 nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
163 nodeMap["PyScript"]=new PythonNode("PyScript");
164 nodeMap["CORBANode"]=new CORBANode("CORBANode");
165 nodeMap["XmlNode"]=new XmlNode("XmlNode");
166 nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
167 nodeMap["CppNode"]=new CppNode("CppNode");
168 nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
169 nodeMap["PresetNode"]=new PresetNode("PresetNode");
170 nodeMap["OutNode"]=new OutNode("OutNode");
171 nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
172 nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
173 composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
174 typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
175 typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
176 typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
177 typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
178 typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
179 typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
180 typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
181 typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
182 std::list<TypeCodeObjref *> ltc;
183 typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
184 typeMap["seqpyobj"]= createSequenceTc("seqpyobj","seqpyobj",typeMap["pyobj"]);
185 composednodeMap["Bloc"]=createBloc("Bloc");
186 composednodeMap["Switch"]=createSwitch("Switch");
187 composednodeMap["WhileLoop"]=createWhileLoop("WhileLoop");
188 composednodeMap["ForLoop"]=createForLoop("ForLoop");
189 composednodeMap["ForEachLoop_double"]=createForEachLoop("ForEachLoop_double",Runtime::_tc_double);
190 composednodeMap["ForEachLoop_string"]=createForEachLoop("ForEachLoop_string",Runtime::_tc_string);
191 composednodeMap["ForEachLoop_int"]=createForEachLoop("ForEachLoop_int",Runtime::_tc_int);
192 composednodeMap["ForEachLoop_bool"]=createForEachLoop("ForEachLoop_bool",Runtime::_tc_bool);
193 composednodeMap["ForEachLoop_pyobj"]=createForEachLoop("ForEachLoop_pyobj",typeMap["pyobj"]);;
194 ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
195 t->addMember("ref",_tc_string);
196 typeMap["dataref"]= t;
199 RuntimeSALOME::RuntimeSALOME(long flags, int argc, char* argv[])
201 // If all flags (apart the IsPyExt flags) are unset, force them to true
202 if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
203 flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
204 + RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
206 // Salome Nodes implies Corba Nodes
207 if (flags & RuntimeSALOME::UseSalome)
208 flags |= RuntimeSALOME::UseCorba;
210 // Corba Nodes implies Python Nodes
211 if (flags & RuntimeSALOME::UseCorba)
212 flags |= RuntimeSALOME::UsePython;
214 _useCorba = flags & RuntimeSALOME::UseCorba;
215 _usePython = flags & RuntimeSALOME::UsePython;
216 _useCpp = flags & RuntimeSALOME::UseCpp;
217 _useXml = flags & RuntimeSALOME::UseXml;
222 if (_useCpp) _setOfImplementation.insert(CppNode::IMPL_NAME);
223 if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
224 if (_useCorba) _setOfImplementation.insert(CORBANode::IMPL_NAME);
225 if (_useXml) _setOfImplementation.insert(XmlNode::IMPL_NAME);
226 init(flags, argc, argv);
229 RuntimeSALOME::~RuntimeSALOME()
231 DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
232 // destroy catalog loader prototypes
233 std::map<std::string, CatalogLoader*>::const_iterator pt;
234 for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
240 //! CORBA and Python initialization
242 * \param flags contains several bits
243 * bit0 (ispyext) true when method is called from Python
244 * (Python initialization must not be done!)
245 * bit1 (UsePython) true if python nodes are needed
246 * bit1 (UseCorba) true if CORBA nodes are needed
247 * bit1 (UseXml) true if python nodes are needed
248 * bit1 (UseCpp) true if C++ nodes are needed
249 * bit1 (UseSalome) true if Salome nodes are needed
250 * \param argc number of command line arguments (used to initialize the Python interpreter)
251 * \param argv command line arguments (used to initialize the Python interpreter)
255 void RuntimeSALOME::init(long flags, int argc, char* argv[])
257 bool ispyext = flags & RuntimeSALOME::IsPyExt;
260 PortableServer::POA_var root_poa;
261 PortableServer::POAManager_var pman;
262 CORBA::Object_var obj;
263 int nbargs = 0; char **args = 0;
264 _orb = CORBA::ORB_init (nbargs, args);
265 obj = _orb->resolve_initial_references("RootPOA");
266 root_poa = PortableServer::POA::_narrow(obj);
267 pman = root_poa->the_POAManager();
271 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
273 obj = _orb->resolve_initial_references("DynAnyFactory");
274 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
279 DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
281 // Initialize Python interpreter in embedded mode
282 if (!Py_IsInitialized())
284 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
287 Py_InitializeEx(0); // do not install signal handlers
289 if (argc > 0 && argv != NULL)
290 PySys_SetArgv(argc, argv);
295 char defaultName[] = "SALOME_YACS_RUNTIME";
296 pyArgv[0] = defaultName;
297 PySys_SetArgv(pyArgc, pyArgv);
299 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
300 PyEval_SaveThread(); /* Release the thread state */
301 //here we do not have the Global Interpreter Lock
304 PyObject *mainmod,*pyapi,*res ;
306 PyGILState_STATE gstate;
307 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
309 mainmod = PyImport_AddModule("__main__");
310 globals = PyModule_GetDict(mainmod);
311 /* globals is a borrowed reference */
313 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
315 PyObject *bimod = PyImport_ImportModule("__builtin__");
316 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
317 Py_FatalError("can't add __builtins__ to __main__");
321 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
327 _omnipy = PyImport_ImportModule((char*)"_omnipy");
331 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
334 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
339 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
342 res=PyRun_String("\n"
343 "from math import *\n"
345 "sys.path.insert(0,'.')\n"
346 "from omniORB import CORBA\n"
347 "from omniORB import any\n"
348 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
349 "#print sys.getrefcount(orb)\n"
355 Py_file_input,globals,globals );
363 _pyorb = PyDict_GetItemString(globals,"orb");
364 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
367 pyany = PyDict_GetItemString(globals,"any");
368 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
371 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
375 PyGILState_Release(gstate); // Release the Global Interpreter Lock
379 // initialize the catalogLoaderFactory map with the session one
380 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
384 void RuntimeSALOME::fini()
388 PyGILState_STATE gstate = PyGILState_Ensure();
390 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
392 PyObject *mainmod, *globals;
393 mainmod = PyImport_AddModule("__main__");
394 globals = PyModule_GetDict(mainmod);
398 res=PyRun_String("orb.destroy()\n"
400 Py_file_input,globals,globals );
406 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
407 delete nodeMap["PyFunction"];
408 delete nodeMap["PyScript"];
409 delete nodeMap["SalomePythonNode"];
410 nodeMap.erase("PyFunction");
411 nodeMap.erase("PyScript");
412 nodeMap.erase("SalomePythonNode");
416 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
424 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
431 std::string RuntimeSALOME::getVersion() const
433 #ifdef YACS_DEVELOPMENT
434 return CORBA::string_dup(YACS_VERSION_STR"dev");
436 return CORBA::string_dup(YACS_VERSION_STR);
440 Proc* RuntimeSALOME::createProc(const std::string& name)
442 return new SalomeProc(name);
445 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
446 std::list<TypeCodeObjref *> ltc)
449 if(id == "") myName = "IDL:" + name + ":1.0";
451 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
454 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
455 const std::string& name,
458 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
461 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
464 if(id == "") myName = "IDL:" + name + ":1.0";
466 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
469 Bloc* RuntimeSALOME::createBloc(const std::string& name)
471 return new Bloc(name);
474 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
476 return new WhileLoop(name);
479 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
481 return new ForLoop(name);
484 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
485 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
487 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
488 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
489 ol->edGetNbOfBranchesPort()->edInit(1);
493 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
498 node = new PresetNode(name);
501 else if(kind == "study" )
503 return new StudyInNode(name);
505 std::string msg="DataNode kind ("+kind+") unknown";
506 throw Exception(msg);
509 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
513 return new OutNode(name);
515 else if(kind == "study" )
517 return new StudyOutNode(name);
520 std::string msg="OutDataNode kind ("+kind+") unknown";
521 throw Exception(msg);
524 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
526 InlineFuncNode* node;
527 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
529 node = new PyFuncNode(name);
532 if(kind == DistributedPythonNode::KIND)
533 return new DistributedPythonNode(name);
534 std::string msg="FuncNode kind ("+kind+") unknown";
535 throw Exception(msg);
538 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
541 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
543 node = new PythonNode(name);
546 std::string msg="ScriptNode kind ("+kind+") unknown";
547 throw Exception(msg);
550 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
553 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
555 node = new CORBANode(name);
558 else if(kind == XmlNode::KIND)
560 node = new XmlNode(name);
563 std::string msg="RefNode kind ("+kind+") unknown";
564 throw Exception(msg);
567 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
570 if(kind == "" || kind == SalomeNode::KIND )
572 node=new SalomeNode(name);
575 else if (kind == CppNode::KIND)
577 node = new CppNode(name);
580 std::string msg="CompoNode kind ("+kind+") unknown";
581 throw Exception(msg);
584 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
586 if(kind == "" || kind == SalomeNode::KIND )
587 return new SalomePythonNode(name);
588 std::string msg="CompoNode kind ("+kind+") unknown";
589 throw Exception(msg);
592 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
593 const std::string& kind)
595 ComponentInstance* compo;
596 if(kind == "" || kind == SalomeComponent::KIND)
597 return new SalomeComponent(name);
598 else if(kind == CORBAComponent::KIND)
599 return new CORBAComponent(name);
600 else if(kind == SalomePythonComponent::KIND)
601 return new SalomePythonComponent(name);
602 else if (kind == CppComponent::KIND)
603 return new CppComponent(name);
604 else if (kind == SalomeHPComponent::KIND)
605 return new SalomeHPComponent(name);
606 std::string msg="Component Instance kind ("+kind+") unknown";
607 throw Exception(msg);
610 Container *RuntimeSALOME::createContainer(const std::string& kind)
612 if(kind == "" || kind == SalomeContainer::KIND)
613 return new SalomeContainer;
614 if(kind==SalomeHPContainer::KIND)
615 return new SalomeHPContainer;
616 else if (kind == CppContainer::KIND)
617 return new CppContainer;
618 std::string msg="Container kind ("+kind+") unknown";
619 throw Exception(msg);
622 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
623 const std::string& impl,
627 if(impl == CppNode::IMPL_NAME)
629 return new InputCppPort(name, node, type);
631 else if(impl == PythonNode::IMPL_NAME)
633 return new InputPyPort(name, node, type);
635 else if(impl == CORBANode::IMPL_NAME)
637 return new InputCorbaPort(name, node, type);
639 else if(impl == XmlNode::IMPL_NAME)
641 return new InputXmlPort(name, node, type);
646 msg << "Cannot create " << impl << " InputPort" ;
647 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
648 throw Exception(msg.str());
652 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
653 const std::string& impl,
657 if(impl == CppNode::IMPL_NAME)
659 return new OutputCppPort(name, node, type);
661 else if(impl == PythonNode::IMPL_NAME)
663 return new OutputPyPort(name, node, type);
665 else if(impl == CORBANode::IMPL_NAME)
667 return new OutputCorbaPort(name, node, type);
669 else if(impl == XmlNode::IMPL_NAME)
671 return new OutputXmlPort(name, node, type);
676 msg << "Cannot create " << impl << " OutputPort" ;
677 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
678 throw Exception(msg.str());
682 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
683 Node *node,TypeCode *type)
685 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
686 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
688 return new InputCalStreamPort(name,node,type);
692 return new InputDataStreamPort(name,node,type);
696 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
697 Node *node,TypeCode *type)
699 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
700 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
702 return new OutputCalStreamPort(name,node,type);
706 return new OutputDataStreamPort(name,node,type);
710 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
712 * \param source : InputPort to be adapted
713 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
714 * \param type : data type provided by the InputPort
715 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
717 * \return : adapted InputPort
719 InputPort* RuntimeSALOME::adapt(InputPort* source,
720 const std::string& impl,
721 TypeCode * type,bool init) throw (ConversionException)
723 string imp_source=source->getNode()->getImplementation();
724 if(imp_source == PythonNode::IMPL_NAME)
726 return adapt((InputPyPort*)source,impl,type,init);
728 else if(imp_source == CppNode::IMPL_NAME)
730 return adapt((InputCppPort*)source,impl,type,init);
732 else if(imp_source == CORBANode::IMPL_NAME)
734 return adapt((InputCorbaPort*)source,impl,type,init);
736 else if(imp_source == XmlNode::IMPL_NAME)
738 return adapt((InputXmlPort*)source,impl,type,init);
740 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
742 return adaptNeutral(source,impl,type,init);
747 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
748 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
749 throw ConversionException(msg.str());
753 //! Adapter function for InPropertyPort
755 * \param source : InPropertyPort to be adapted
756 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
757 * \param type : data type provided by the InPropertyPort
758 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
760 * \return : adapted InputPort
762 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
763 const std::string& impl,
764 TypeCode * type,bool init) throw (ConversionException)
766 return adaptNeutral((InputPort *)source,impl,type,init);
769 //! Adapt a Neutral input port to a Corba output port
771 * \param inport : Neutral input port to adapt to Corba type type
772 * \param type : output port type
773 * \return an adaptated input port of type InputCorbaPort
775 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
776 TypeCode * type) throw (ConversionException)
778 // BEWARE : using the generic check
779 if(inport->edGetType()->isAdaptable(type))
781 //the output data is convertible to inport type
782 return new CorbaNeutral(inport);
784 //non convertible type
786 msg << "Cannot connect Corba output port with type: " << type->id() ;
787 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
789 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
791 throw ConversionException(msg.str());
794 //! Adapt a Neutral input port to a Python output port
796 * \param inport : input port to adapt to Python type type
797 * \param type : output port type
798 * \return an adaptated input port of type InputPyPort
800 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
801 TypeCode * type) throw (ConversionException)
803 // BEWARE : using the generic check
804 if(inport->edGetType()->isAdaptable(type))
807 return new PyNeutral(inport);
809 //non convertible type
811 msg << "Cannot connect Python output port with type: " << type->id() ;
812 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
814 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
816 throw ConversionException(msg.str());
819 //! Adapt a Neutral input port to a Xml output port
821 * \param inport : input port to adapt to Xml type type
822 * \param type : output port type
823 * \return an input port of type InputXmlPort
825 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
826 TypeCode * type) throw (ConversionException)
828 // BEWARE : using the generic check
829 if(inport->edGetType()->isAdaptable(type))
832 return new XmlNeutral(inport);
834 //non convertible type
836 msg << "Cannot connect Xml output port with type: " << type->id() ;
837 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
839 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
841 throw ConversionException(msg.str());
844 //! Adapt a Neutral input port to a C++ output port
846 * \param inport : input port to adapt to C++ type type
847 * \param type : output port type
848 * \return an input port of type InputCppPort
850 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
851 TypeCode * type) throw (ConversionException)
853 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
854 if(isAdaptableNeutralCpp(type,inport->edGetType()))
857 return new CppNeutral(inport);
859 //non convertible type
861 msg << "Cannot connect Cpp output port with type: " << type->id() ;
862 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
864 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
866 throw ConversionException(msg.str());
869 //! Adapt a Neutral input port to connect it to an output port with a given implementation
871 * \param source : Neutral input port to adapt to implementation impl and type type
872 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
873 * \param type : output port supported type
874 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
875 * \return the adaptated port
877 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
878 const std::string& impl,
879 TypeCode * type,bool init) throw (ConversionException)
881 if(impl == CppNode::IMPL_NAME)
883 return adaptNeutralToCpp(source,type);
885 else if(impl == PythonNode::IMPL_NAME)
887 return adaptNeutralToPython(source,type);
889 else if(impl == CORBANode::IMPL_NAME)
891 return adaptNeutralToCorba(source,type);
893 else if(impl == XmlNode::IMPL_NAME )
895 return adaptNeutralToXml(source,type);
897 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
900 return new NeutralInit(source);
902 return new ProxyPort(source);
905 msg << "Cannot connect InputPort : unknown implementation " << impl;
906 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
907 throw ConversionException(msg.str());
910 //! Adapt a XML input port to connect it to a CORBA output port
912 * \param inport : input port to adapt to CORBA type type
913 * \param type : type supported by output port
914 * \return an adaptator port of type InputCorbaPort
917 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
918 TypeCode * type) throw (ConversionException)
920 if(isAdaptableXmlCorba(type,inport->edGetType()))
922 //output type is convertible to input type
923 return new CorbaXml(inport);
925 //output type is not convertible
927 msg << "Cannot connect Corba output port with type: " << type->id() ;
928 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
930 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
932 throw ConversionException(msg.str());
935 //! Adapt a XML input port to a Python output port
937 * \param inport : input port to adapt to Python type type
938 * \param type : output port type
939 * \return an adaptated input port of type InputPyPort
941 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
942 TypeCode * type) throw (ConversionException)
944 if(inport->edGetType()->isAdaptable(type))
946 //the output data is convertible to inport type
947 return new PyXml(inport);
949 //non convertible type
951 msg << "Cannot connect Python output port with type: " << type->id() ;
952 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
954 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
956 throw ConversionException(msg.str());
959 //! Adapt a XML input port to a C++ output port
961 * \param inport : input port to adapt to C++ type type
962 * \param type : output port type
963 * \return an adaptated input port of type InputPyPort
965 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
966 TypeCode * type) throw (ConversionException)
968 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
969 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
970 if(type->isAdaptable(inport->edGetType()))
972 //the output data is convertible to inport type
973 return new CppXml(inport);
975 //non convertible type
977 msg << "Cannot connect Cpp output port with type: " << type->id() ;
978 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
980 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
982 throw ConversionException(msg.str());
985 //! Adapt a XML input port to a Neutral output port
987 * \param inport : input port to adapt to Neutral type type
988 * \param type : output port type
989 * \return an adaptated input port of type Neutralxxxx
991 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
992 TypeCode * type) throw (ConversionException)
994 if(inport->edGetType()->isAdaptable(type))
996 //the output data is convertible to inport type
997 return new NeutralXml(inport);
999 //non convertible type
1001 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
1002 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
1003 throw ConversionException(msg.str());
1006 //! Adapt a XML input port to a Xml output port
1008 * \param inport : input port to adapt to Xml type type
1009 * \param type : output port type
1010 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1011 * \return an adaptated input port of type Xmlxxxx
1013 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
1014 TypeCode * type,bool init) throw (ConversionException)
1017 return new ProxyPort(inport);
1019 if(inport->edGetType()->isAdaptable(type))
1020 return new ProxyPort(inport);
1023 msg << "Cannot connect Xml output port with type: " << type->id() ;
1024 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1026 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1028 throw ConversionException(msg.str());
1031 //! Adapt an Xml input port to an output port which implementation is given by impl
1033 * \param source : input port to adapt to implementation impl and type type
1034 * \param impl : output port implementation (C++, Python or Corba)
1035 * \param type : output port supported type
1036 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1037 * \return the adaptated port
1040 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1041 const std::string& impl,
1042 TypeCode * type,bool init) throw (ConversionException)
1044 if(impl == CORBANode::IMPL_NAME)
1046 return adaptXmlToCorba(source,type);
1048 else if(impl == PythonNode::IMPL_NAME)
1050 return adaptXmlToPython(source,type);
1052 else if(impl == CppNode::IMPL_NAME)
1054 return adaptXmlToCpp(source,type);
1056 else if(impl == XmlNode::IMPL_NAME )
1058 return adaptXmlToXml(source,type,init);
1060 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1062 return adaptXmlToNeutral(source,type);
1067 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1068 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1069 throw ConversionException(msg.str());
1074 //! Adapt a CORBA input port to a CORBA output port
1076 * \param inport : input port to adapt to CORBA outport data type
1077 * \param type : outport data type
1078 * \return an adaptator port of type InputCORBAPort
1080 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1081 TypeCode * type) throw (ConversionException)
1083 if(type->isA(inport->edGetType()))
1085 //types are compatible : no conversion
1086 //outport data type is more specific than inport required type
1087 //so the inport can be used safely
1088 return new ProxyPort(inport);
1090 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1092 //ouport data can be converted to inport data type
1093 return new CorbaCorba(inport);
1095 //outport data can not be converted
1097 msg << "Cannot connect Corba output port with type: " << type->id() ;
1098 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1100 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1102 throw ConversionException(msg.str());
1105 //! Adapt a CORBA input port to a Python output port
1107 * \param inport : input port to adapt to Python type type
1108 * \param type : outport data type
1109 * \return an adaptator port of type InputPyPort
1112 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1113 TypeCode * type) throw (ConversionException)
1115 if(inport->edGetType()->kind() == Double)
1117 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1119 else if(inport->edGetType()->kind() == Int)
1121 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1123 else if(inport->edGetType()->kind() == String)
1125 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1127 else if(inport->edGetType()->kind() == Bool)
1129 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1131 else if(inport->edGetType()->kind() == Objref )
1133 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1135 return new PyCorbaObjref(inport);
1140 msg << "Cannot connect Python output port with type: " << type->id() ;
1141 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1142 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1143 throw ConversionException(msg.str());
1146 else if(inport->edGetType()->kind() == Sequence)
1148 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1150 return new PyCorbaSequence(inport);
1155 msg << "Cannot convert this sequence type " ;
1156 msg << __FILE__ << ":" <<__LINE__;
1157 throw ConversionException(msg.str());
1160 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1162 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1164 return new PyCorbaStruct(inport);
1169 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1170 msg << __FILE__ << ":" <<__LINE__;
1171 throw ConversionException(msg.str());
1174 // Adaptation not possible
1176 msg << "Cannot connect Python output port with type: " << type->id() ;
1177 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1179 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1181 throw ConversionException(msg.str());
1184 //! Adapt a CORBA input port to connect it to a XML output port
1186 * \param inport : input port to adapt to Xml type type
1187 * \param type : type supported by output port
1188 * \return an adaptator port of type InputXmlPort
1191 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1192 TypeCode * type) throw (ConversionException)
1194 // BEWARE : using the generic check
1195 if(inport->edGetType()->isAdaptable(type))
1197 //output type is convertible to input type
1198 return new XmlCorba(inport);
1200 //output type is not convertible
1202 msg << "Cannot connect Xml output port with type: " << type->id() ;
1203 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1205 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1207 throw ConversionException(msg.str());
1210 //! Adapt a CORBA input port to a C++ output port
1212 * \param inport : input port to adapt to C++ type type
1213 * \param type : outport data type
1214 * \return an adaptator port of type InputCPPPort
1217 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1218 TypeCode * type) throw (ConversionException)
1220 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1221 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1223 //output type is convertible to input type
1224 return new CppCorba(inport);
1226 //output type is not convertible
1228 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1229 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1231 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1233 throw ConversionException(msg.str());
1236 //! Adapt a CORBA input port to a neutral data
1238 * \param inport : InputPort to adapt to Neutral type type
1239 * \param type : outport data type
1240 * \return an adaptator port of type Neutralxxxx
1243 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1244 TypeCode * type) throw (ConversionException)
1246 if(inport->edGetType()->kind() == Double)
1248 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1250 else if(inport->edGetType()->kind() == Int)
1252 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1254 else if(inport->edGetType()->kind() == String)
1256 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1258 else if(inport->edGetType()->kind() == Bool)
1260 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1262 else if(inport->edGetType()->kind() == Objref)
1264 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1266 else if(inport->edGetType()->kind() == Sequence)
1268 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1269 return new NeutralCorbaSequence(inport);
1273 msg << "Cannot convert this sequence type " ;
1274 msg << __FILE__ << ":" <<__LINE__;
1275 throw ConversionException(msg.str());
1278 else if(inport->edGetType()->kind() == Struct)
1280 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1283 // Adaptation not possible
1285 msg << "Cannot connect Neutral 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 an output which implementation and type are given by impl and type
1295 * \param source : input port to adapt to implementation impl and type type
1296 * \param impl : output port implementation (C++, Python or Corba)
1297 * \param type : outport data type
1298 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1299 * \return an adaptator port which type depends on impl
1302 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1303 const std::string& impl,
1304 TypeCode * type,bool init) throw (ConversionException)
1306 if(impl == CppNode::IMPL_NAME)
1308 return adaptCorbaToCpp(source,type);
1310 else if(impl == PythonNode::IMPL_NAME)
1312 return adaptCorbaToPython(source,type);
1314 else if(impl == CORBANode::IMPL_NAME)
1317 return adaptCorbaToCorba(source,type);
1319 return adaptCorbaToCorba(source,type);
1321 else if(impl == XmlNode::IMPL_NAME )
1323 return adaptCorbaToXml(source,type);
1325 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1327 return adaptCorbaToNeutral(source,type);
1332 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1333 msg << __FILE__ << ":" <<__LINE__;
1334 throw ConversionException(msg.str());
1338 //! Adapt a Python input port to a Python output port
1340 * No need to make conversion or cast.
1341 * Only check, it's possible.
1342 * \param inport : InputPort to adapt to Python type type
1343 * \param type : outport data type
1344 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1345 * \return an adaptator port of type InputPyPort
1348 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1349 TypeCode * type,bool init) throw (ConversionException)
1352 return new PyInit(inport);
1354 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1356 //output data is convertible to input type
1357 //With python, no need to convert. Conversion will be done automatically
1358 //by the interpreter
1359 return new ProxyPort(inport);
1361 //output data is not convertible to input type
1363 msg << "Cannot connect Python output port with type: " << type->id() ;
1364 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1366 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1368 throw ConversionException(msg.str());
1371 //! Adapt a Python input port to a C++ output port
1373 * \param inport : InputPort to adapt to C++ type type
1374 * \param type : outport data type
1375 * \return an adaptator port of C++ type (InputCppPort)
1378 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1379 TypeCode * type) throw (ConversionException)
1381 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1382 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1384 //output type is convertible to input type
1385 return new CppPy(inport);
1387 //output type is not convertible
1389 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1390 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1392 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1394 throw ConversionException(msg.str());
1397 //! Adapt a Python input port to a Neutral data port
1399 * \param inport : InputPort to adapt to Neutral type type
1400 * \param type : outport data type
1401 * \return an adaptator port of Neutral type (Neutralxxxx)
1404 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1405 TypeCode * type) throw (ConversionException)
1407 if(inport->edGetType()->kind() == Double)
1409 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1411 else if(inport->edGetType()->kind() == Int)
1413 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1415 else if(inport->edGetType()->kind() == String)
1417 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1419 else if(inport->edGetType()->kind() == Bool)
1421 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1423 else if(inport->edGetType()->kind() == Objref)
1425 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1427 else if(inport->edGetType()->kind() == Sequence)
1429 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1430 return new NeutralPySequence(inport);
1434 msg << "Cannot convert this sequence type " ;
1435 msg << __FILE__ << ":" <<__LINE__;
1436 throw ConversionException(msg.str());
1439 else if(inport->edGetType()->kind() == Struct)
1441 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1444 // Adaptation not possible
1446 msg << "Cannot connect Neutral 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 Corba output port
1456 * Always convert the data
1457 * \param inport : InputPort to adapt to Corba type type
1458 * \param type : outport data type
1459 * \return an adaptator port of Corba type (InputCorbaPort)
1462 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1463 TypeCode * type) throw (ConversionException)
1465 if(inport->edGetType()->kind() == Double)
1467 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1469 else if(inport->edGetType()->kind() == Int)
1471 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1473 else if(inport->edGetType()->kind() == String)
1475 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1477 else if(inport->edGetType()->kind() == Bool)
1479 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1481 else if(inport->edGetType()->kind() == Objref)
1483 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1485 return new CorbaPyObjref(inport);
1490 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1491 msg << " " << __FILE__ << ":" <<__LINE__;
1492 throw ConversionException(msg.str());
1495 else if(inport->edGetType()->kind() == Sequence)
1497 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1499 return new CorbaPySequence(inport);
1504 msg << "Cannot convert this sequence type " ;
1505 msg << __FILE__ << ":" <<__LINE__;
1506 throw ConversionException(msg.str());
1509 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1511 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1513 return new CorbaPyStruct(inport);
1518 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1519 msg << " " << __FILE__ << ":" <<__LINE__;
1520 throw ConversionException(msg.str());
1523 // Adaptation not possible
1525 msg << "Cannot connect Corba output port with type: " << type->id() ;
1526 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1528 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1530 throw ConversionException(msg.str());
1533 //! Adapt a Python input port to a Xml output port
1535 * \param inport : input port to adapt to Xml type type
1536 * \param type : output port type
1537 * \return an input port of type InputXmlPort
1540 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1541 TypeCode * type) throw (ConversionException)
1543 // BEWARE : using the generic check
1544 if(inport->edGetType()->isAdaptable(type))
1547 return new XmlPython(inport);
1549 //non convertible type
1551 msg << "Cannot connect Xml output port with type: " << type->id() ;
1552 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1554 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1556 throw ConversionException(msg.str());
1559 //! Adapt a Python input port to an output port with a given implementation
1561 * \param source : input port to adapt to implementation impl and type type
1562 * \param impl : output port implementation (C++, Python or Corba)
1563 * \param type : output port type
1564 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1565 * \return adaptated input port
1568 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1569 const std::string& impl,
1570 TypeCode * type,bool init) throw (ConversionException)
1572 if(impl == CppNode::IMPL_NAME)
1574 return adaptPythonToCpp(source,type);
1576 else if(impl == PythonNode::IMPL_NAME)
1578 return adaptPythonToPython(source,type,init);
1580 else if(impl == CORBANode::IMPL_NAME)
1582 return adaptPythonToCorba(source,type);
1584 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1586 return adaptPythonToNeutral(source,type);
1588 else if(impl == XmlNode::IMPL_NAME)
1590 return adaptPythonToXml(source,type);
1595 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1596 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1597 throw ConversionException(msg.str());
1602 //! Adapt a C++ input port to connect it to a CORBA output port
1604 * \param inport : input port to adapt to CORBA type type
1605 * \param type : type supported by output port
1606 * \return an adaptator port of type InputCorbaPort
1609 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1610 TypeCode * type) throw (ConversionException)
1612 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1613 if(isAdaptableCppCorba(type,inport->edGetType()))
1615 //output type is convertible to input type
1616 return new CorbaCpp(inport);
1618 //output type is not convertible
1620 msg << "Cannot connect Corba output port with type: " << type->id() ;
1621 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1623 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1625 throw ConversionException(msg.str());
1628 //! Adapt a C++ input port to a Python output port
1630 * \param inport : input port to adapt to Python type type
1631 * \param type : output port type
1632 * \return an adaptated input port of type InputPyPort
1634 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1635 TypeCode * type) throw (ConversionException)
1637 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1638 if(isAdaptableCppPyObject(type,inport->edGetType()))
1640 //output type is convertible to input type
1641 return new PyCpp(inport);
1643 //output type is not convertible
1645 msg << "Cannot connect Python output port with type: " << type->id() ;
1646 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1648 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1650 throw ConversionException(msg.str());
1653 //! Adapt a C++ input port to a C++ output port
1655 * \param inport : input port to adapt to C++ type type
1656 * \param type : output port type
1657 * \return an adaptated input port of type InputPyPort
1659 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1660 TypeCode * type) throw (ConversionException)
1662 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1663 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1664 if(type->isAdaptable(inport->edGetType()))
1666 //the output data is convertible to inport type
1667 return new CppCpp(inport);
1669 //non convertible type
1671 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1672 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1674 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1676 throw ConversionException(msg.str());
1679 //! Adapt a C++ input port to a Neutral output port
1681 * \param inport : input port to adapt to C++ type type
1682 * \param type : output port type
1683 * \return an adaptated input port of type InputPyPort
1685 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1686 TypeCode * type) throw (ConversionException)
1688 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1689 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1690 if(type->isAdaptable(inport->edGetType()))
1692 //the output data is convertible to inport type
1693 return new NeutralCpp(inport);
1695 //non convertible type
1697 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1698 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1700 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1702 throw ConversionException(msg.str());
1705 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1706 TypeCode * type) throw (ConversionException)
1708 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1709 if(isAdaptableCppXml(type,inport->edGetType()))
1712 return new XmlCpp(inport);
1714 //non convertible type
1716 msg << "Cannot connect Xml output port with type: " << type->id() ;
1717 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1719 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1721 throw ConversionException(msg.str());
1724 //! Adapt a C++ input port to connect it to an output port with a given implementation
1726 * \param source : input port to adapt to implementation impl and type type
1727 * \param impl : output port implementation (C++, Python or Corba)
1728 * \param type : output port supported type
1729 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1730 * \return the adaptated port
1733 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1734 const std::string& impl,
1735 TypeCode * type,bool init) throw (ConversionException)
1737 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1738 if(impl == CORBANode::IMPL_NAME)
1740 return adaptCppToCorba(source,type);
1742 else if(impl == PythonNode::IMPL_NAME)
1744 return adaptCppToPython(source,type);
1746 else if(impl == XmlNode::IMPL_NAME)
1748 return adaptCppToXml(source,type);
1750 else if(impl == CppNode::IMPL_NAME)
1752 return adaptCppToCpp(source, type);
1754 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1756 return adaptCppToNeutral(source, type);
1761 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1762 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1763 throw ConversionException(msg.str());
1767 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1768 // const InputPort* inputPort)
1770 // bool result=true;
1774 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1779 PyObject * RuntimeSALOME::getPyOrb()
1784 PyObject * RuntimeSALOME::getBuiltins()
1789 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1794 PyObject * RuntimeSALOME::get_omnipy()
1799 omniORBpyAPI* RuntimeSALOME::getApi()
1804 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1807 return (void *)convertNeutralPyObject(type,data);
1811 return (void *)Py_None;
1815 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1820 // The call to PyGILState_Ensure was moved here because there was also
1821 // a crash when calling convertNeutralPyObject with a sequence of pyobj.
1822 // see also the comment below.
1823 PyGILState_STATE gstate = PyGILState_Ensure();
1824 ob=convertNeutralPyObject(type,data);
1825 std::string s=convertPyObjectToString(ob);
1827 // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1828 // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1829 // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1830 // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1831 // feel free to change this code.
1832 //PyGILState_STATE gstate = PyGILState_Ensure();
1834 PyGILState_Release(gstate);
1843 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1845 return YACS::ENGINE::convertPyObjectToString(ob);
1848 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1853 PyGILState_STATE gstate = PyGILState_Ensure();
1854 mainmod = PyImport_AddModule("__main__");
1855 globals = PyModule_GetDict(mainmod);
1856 PyObject* d = PyDict_New();
1857 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1858 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1864 PyObject* new_stderr = newPyStdOut(error);
1865 PySys_SetObject((char *)"stderr", new_stderr);
1867 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1868 Py_DECREF(new_stderr);
1869 PyGILState_Release(gstate);
1870 throw Exception(error);
1872 PyGILState_Release(gstate);