1 // Copyright (C) 2006-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #define private public
24 #define protected public
25 #include <omniORB4/CORBA.h>
26 #include <omniORB4/internal/typecode.h>
27 #include <omniORB4/internal/corbaOrb.h>
30 #include "yacsconfig.h"
31 #include "YACS_version.h"
32 #include "RuntimeSALOME.hxx"
33 #include "SALOMEDispatcher.hxx"
35 #include "TypeCode.hxx"
36 #include "WhileLoop.hxx"
37 #include "ForLoop.hxx"
38 #include "SalomeOptimizerLoop.hxx"
40 #include "InputPort.hxx"
41 #include "OutputPort.hxx"
42 #include "PresetPorts.hxx"
43 #include "InputDataStreamPort.hxx"
44 #include "OutputDataStreamPort.hxx"
45 #include "SalomeProc.hxx"
46 #include "PyStdout.hxx"
48 #include "SessionCataLoader.hxx"
51 #include "CORBAComponent.hxx"
52 #include "SalomeComponent.hxx"
53 #include "SalomePythonComponent.hxx"
54 #include "CppComponent.hxx"
56 #include "SalomeContainer.hxx"
57 #include "CppContainer.hxx"
58 #include "SalomeHPContainer.hxx"
61 #include "PythonNode.hxx"
62 #include "CORBANode.hxx"
63 #include "XMLNode.hxx"
64 #include "CppNode.hxx"
65 #include "PresetNode.hxx"
66 #include "OutNode.hxx"
67 #include "StudyNodes.hxx"
68 #include "SalomePythonNode.hxx"
69 #include "DistributedPythonNode.hxx"
72 #include "CORBACORBAConv.hxx"
73 #include "CORBAPythonConv.hxx"
74 #include "CORBAXMLConv.hxx"
75 #include "CORBACppConv.hxx"
76 #include "CORBANeutralConv.hxx"
78 #include "TypeConversions.hxx"
80 #include "PythonCORBAConv.hxx"
81 #include "PythonXMLConv.hxx"
82 #include "PythonCppConv.hxx"
83 #include "PythonNeutralConv.hxx"
84 #include "PythonInitConv.hxx"
87 #include "NeutralCORBAConv.hxx"
88 #include "NeutralPythonConv.hxx"
89 #include "NeutralXMLConv.hxx"
90 #include "NeutralCppConv.hxx"
91 #include "NeutralInitConv.hxx"
94 #include "CppCORBAConv.hxx"
95 #include "CppPythonConv.hxx"
96 #include "CppXMLConv.hxx"
97 #include "CppCppConv.hxx"
98 #include "CppNeutralConv.hxx"
101 #include "XMLCORBAConv.hxx"
102 #include "XMLPythonConv.hxx"
103 #include "XMLCppConv.hxx"
104 #include "XMLNeutralConv.hxx"
106 //Calcium specific ports
107 #include "CalStreamPort.hxx"
110 #include "SALOME_NamingService.hxx"
111 #include "SALOME_LifeCycleCORBA.hxx"
114 #include <libxml/parser.h>
115 #include <omniORB4/CORBA.h>
121 #include "YacsTrace.hxx"
124 using namespace YACS::ENGINE;
126 void RuntimeSALOME::setRuntime(long flags, int argc, char* argv[]) // singleton creation (not thread safe!)
128 if (! Runtime::_singleton)
130 RuntimeSALOME* r=new RuntimeSALOME(flags, argc, argv);
131 Runtime::_singleton = r;
134 DEBTRACE("RuntimeSALOME::setRuntime() done !");
137 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
139 YASSERT(Runtime::_singleton);
140 return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
144 * Singleton creation, initialize converter map
147 RuntimeSALOME::RuntimeSALOME()
152 void RuntimeSALOME::initBuiltins()
154 //Fill the builtin catalog with nodes specific to the runtime
155 std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
156 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
157 std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
158 std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
159 nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
160 nodeMap["PyScript"]=new PythonNode("PyScript");
161 nodeMap["CORBANode"]=new CORBANode("CORBANode");
162 nodeMap["XmlNode"]=new XmlNode("XmlNode");
163 nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
164 nodeMap["CppNode"]=new CppNode("CppNode");
165 nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
166 nodeMap["PresetNode"]=new PresetNode("PresetNode");
167 nodeMap["OutNode"]=new OutNode("OutNode");
168 nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
169 nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
170 composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
171 typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
172 typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
173 typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
174 typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
175 typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
176 typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
177 typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
178 typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
179 std::list<TypeCodeObjref *> ltc;
180 typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
181 ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
182 t->addMember("ref",_tc_string);
183 typeMap["dataref"]= t;
186 RuntimeSALOME::RuntimeSALOME(long flags, int argc, char* argv[])
188 // If all flags (apart the IsPyExt flags) are unset, force them to true
189 if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
190 flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
191 + RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
193 // Salome Nodes implies Corba Nodes
194 if (flags & RuntimeSALOME::UseSalome)
195 flags |= RuntimeSALOME::UseCorba;
197 // Corba Nodes implies Python Nodes
198 if (flags & RuntimeSALOME::UseCorba)
199 flags |= RuntimeSALOME::UsePython;
201 _useCorba = flags & RuntimeSALOME::UseCorba;
202 _usePython = flags & RuntimeSALOME::UsePython;
203 _useCpp = flags & RuntimeSALOME::UseCpp;
204 _useXml = flags & RuntimeSALOME::UseXml;
209 if (_useCpp) _setOfImplementation.insert(CppNode::IMPL_NAME);
210 if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
211 if (_useCorba) _setOfImplementation.insert(CORBANode::IMPL_NAME);
212 if (_useXml) _setOfImplementation.insert(XmlNode::IMPL_NAME);
213 init(flags, argc, argv);
216 RuntimeSALOME::~RuntimeSALOME()
218 DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
219 // destroy catalog loader prototypes
220 std::map<std::string, CatalogLoader*>::const_iterator pt;
221 for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
227 //! CORBA and Python initialization
229 * \param flags contains several bits
230 * bit0 (ispyext) true when method is called from Python
231 * (Python initialization must not be done!)
232 * bit1 (UsePython) true if python nodes are needed
233 * bit1 (UseCorba) true if CORBA nodes are needed
234 * bit1 (UseXml) true if python nodes are needed
235 * bit1 (UseCpp) true if C++ nodes are needed
236 * bit1 (UseSalome) true if Salome nodes are needed
237 * \param argc number of command line arguments (used to initialize the Python interpreter)
238 * \param argv command line arguments (used to initialize the Python interpreter)
242 void RuntimeSALOME::init(long flags, int argc, char* argv[])
244 bool ispyext = flags & RuntimeSALOME::IsPyExt;
247 PortableServer::POA_var root_poa;
248 PortableServer::POAManager_var pman;
249 CORBA::Object_var obj;
250 int nbargs = 0; char **args = 0;
251 _orb = CORBA::ORB_init (nbargs, args);
252 obj = _orb->resolve_initial_references("RootPOA");
253 root_poa = PortableServer::POA::_narrow(obj);
254 pman = root_poa->the_POAManager();
258 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
260 obj = _orb->resolve_initial_references("DynAnyFactory");
261 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
266 DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
268 // Initialize Python interpreter in embedded mode
269 if (!Py_IsInitialized())
271 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
274 Py_InitializeEx(0); // do not install signal handlers
276 if (argc > 0 && argv != NULL)
277 PySys_SetArgv(argc, argv);
282 char defaultName[] = "SALOME_YACS_RUNTIME";
283 pyArgv[0] = defaultName;
284 PySys_SetArgv(pyArgc, pyArgv);
286 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
287 PyEval_SaveThread(); /* Release the thread state */
288 //here we do not have the Global Interpreter Lock
291 PyObject *mainmod,*pyapi,*res ;
293 PyGILState_STATE gstate;
294 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
296 mainmod = PyImport_AddModule("__main__");
297 globals = PyModule_GetDict(mainmod);
298 /* globals is a borrowed reference */
300 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
302 PyObject *bimod = PyImport_ImportModule("__builtin__");
303 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
304 Py_FatalError("can't add __builtins__ to __main__");
308 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
314 _omnipy = PyImport_ImportModule((char*)"_omnipy");
318 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
321 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
326 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
329 res=PyRun_String("\n"
330 "from math import *\n"
332 "sys.path.insert(0,'.')\n"
333 "from omniORB import CORBA\n"
334 "from omniORB import any\n"
335 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
336 "#print sys.getrefcount(orb)\n"
342 Py_file_input,globals,globals );
350 _pyorb = PyDict_GetItemString(globals,"orb");
351 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
354 pyany = PyDict_GetItemString(globals,"any");
355 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
358 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
362 PyGILState_Release(gstate); // Release the Global Interpreter Lock
366 // initialize the catalogLoaderFactory map with the session one
367 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
371 void RuntimeSALOME::fini()
375 PyGILState_STATE gstate = PyGILState_Ensure();
377 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
379 PyObject *mainmod, *globals;
380 mainmod = PyImport_AddModule("__main__");
381 globals = PyModule_GetDict(mainmod);
385 res=PyRun_String("orb.destroy()\n"
387 Py_file_input,globals,globals );
393 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
394 delete nodeMap["PyFunction"];
395 delete nodeMap["PyScript"];
396 delete nodeMap["SalomePythonNode"];
397 nodeMap.erase("PyFunction");
398 nodeMap.erase("PyScript");
399 nodeMap.erase("SalomePythonNode");
403 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
411 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
418 std::string RuntimeSALOME::getVersion() const
420 #ifdef YACS_DEVELOPMENT
421 return CORBA::string_dup(YACS_VERSION_STR"dev");
423 return CORBA::string_dup(YACS_VERSION_STR);
427 Proc* RuntimeSALOME::createProc(const std::string& name)
429 return new SalomeProc(name);
432 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
433 std::list<TypeCodeObjref *> ltc)
436 if(id == "") myName = "IDL:" + name + ":1.0";
438 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
441 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
442 const std::string& name,
445 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
448 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
451 if(id == "") myName = "IDL:" + name + ":1.0";
453 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
456 Bloc* RuntimeSALOME::createBloc(const std::string& name)
458 return new Bloc(name);
461 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
463 return new WhileLoop(name);
466 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
468 return new ForLoop(name);
471 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
472 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
474 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
475 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
476 ol->edGetNbOfBranchesPort()->edInit(1);
480 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
485 node = new PresetNode(name);
488 else if(kind == "study" )
490 return new StudyInNode(name);
492 std::string msg="DataNode kind ("+kind+") unknown";
493 throw Exception(msg);
496 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
500 return new OutNode(name);
502 else if(kind == "study" )
504 return new StudyOutNode(name);
507 std::string msg="OutDataNode kind ("+kind+") unknown";
508 throw Exception(msg);
511 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
513 InlineFuncNode* node;
514 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
516 node = new PyFuncNode(name);
519 if(kind == DistributedPythonNode::KIND)
520 return new DistributedPythonNode(name);
521 std::string msg="FuncNode kind ("+kind+") unknown";
522 throw Exception(msg);
525 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
528 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
530 node = new PythonNode(name);
533 std::string msg="ScriptNode kind ("+kind+") unknown";
534 throw Exception(msg);
537 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
540 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
542 node = new CORBANode(name);
545 else if(kind == XmlNode::KIND)
547 node = new XmlNode(name);
550 std::string msg="RefNode kind ("+kind+") unknown";
551 throw Exception(msg);
554 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
557 if(kind == "" || kind == SalomeNode::KIND )
559 node=new SalomeNode(name);
562 else if (kind == CppNode::KIND)
564 node = new CppNode(name);
567 std::string msg="CompoNode kind ("+kind+") unknown";
568 throw Exception(msg);
571 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
573 if(kind == "" || kind == SalomeNode::KIND )
574 return new SalomePythonNode(name);
575 std::string msg="CompoNode kind ("+kind+") unknown";
576 throw Exception(msg);
579 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
580 const std::string& kind)
582 ComponentInstance* compo;
583 if(kind == "" || kind == SalomeComponent::KIND)
584 return new SalomeComponent(name);
585 else if(kind == CORBAComponent::KIND)
586 return new CORBAComponent(name);
587 else if(kind == SalomePythonComponent::KIND)
588 return new SalomePythonComponent(name);
589 else if (kind == CppComponent::KIND)
590 return new CppComponent(name);
591 std::string msg="Component Instance kind ("+kind+") unknown";
592 throw Exception(msg);
595 Container *RuntimeSALOME::createContainer(const std::string& kind)
597 if(kind == "" || kind == SalomeComponent::KIND)
598 return new SalomeContainer;
599 if(kind==SalomeHPContainer::KIND)
600 return new SalomeHPContainer;
601 else if (kind == CppComponent::KIND)
602 return new CppContainer;
603 std::string msg="Container kind ("+kind+") unknown";
604 throw Exception(msg);
607 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
608 const std::string& impl,
612 if(impl == CppNode::IMPL_NAME)
614 return new InputCppPort(name, node, type);
616 else if(impl == PythonNode::IMPL_NAME)
618 return new InputPyPort(name, node, type);
620 else if(impl == CORBANode::IMPL_NAME)
622 return new InputCorbaPort(name, node, type);
624 else if(impl == XmlNode::IMPL_NAME)
626 return new InputXmlPort(name, node, type);
631 msg << "Cannot create " << impl << " InputPort" ;
632 msg << " ("__FILE__ << ":" << __LINE__ << ")";
633 throw Exception(msg.str());
637 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
638 const std::string& impl,
642 if(impl == CppNode::IMPL_NAME)
644 return new OutputCppPort(name, node, type);
646 else if(impl == PythonNode::IMPL_NAME)
648 return new OutputPyPort(name, node, type);
650 else if(impl == CORBANode::IMPL_NAME)
652 return new OutputCorbaPort(name, node, type);
654 else if(impl == XmlNode::IMPL_NAME)
656 return new OutputXmlPort(name, node, type);
661 msg << "Cannot create " << impl << " OutputPort" ;
662 msg << " ("__FILE__ << ":" << __LINE__ << ")";
663 throw Exception(msg.str());
667 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
668 Node *node,TypeCode *type)
670 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
671 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
673 return new InputCalStreamPort(name,node,type);
677 return new InputDataStreamPort(name,node,type);
681 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
682 Node *node,TypeCode *type)
684 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
685 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
687 return new OutputCalStreamPort(name,node,type);
691 return new OutputDataStreamPort(name,node,type);
695 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
697 * \param source : InputPort to be adapted
698 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
699 * \param type : data type provided by the InputPort
700 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
702 * \return : adapted InputPort
704 InputPort* RuntimeSALOME::adapt(InputPort* source,
705 const std::string& impl,
706 TypeCode * type,bool init) throw (ConversionException)
708 string imp_source=source->getNode()->getImplementation();
709 if(imp_source == PythonNode::IMPL_NAME)
711 return adapt((InputPyPort*)source,impl,type,init);
713 else if(imp_source == CppNode::IMPL_NAME)
715 return adapt((InputCppPort*)source,impl,type,init);
717 else if(imp_source == CORBANode::IMPL_NAME)
719 return adapt((InputCorbaPort*)source,impl,type,init);
721 else if(imp_source == XmlNode::IMPL_NAME)
723 return adapt((InputXmlPort*)source,impl,type,init);
725 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
727 return adaptNeutral(source,impl,type,init);
732 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
733 msg << " ("__FILE__ << ":" << __LINE__ << ")";
734 throw ConversionException(msg.str());
738 //! Adapter function for InPropertyPort
740 * \param source : InPropertyPort to be adapted
741 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
742 * \param type : data type provided by the InPropertyPort
743 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
745 * \return : adapted InputPort
747 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
748 const std::string& impl,
749 TypeCode * type,bool init) throw (ConversionException)
751 return adaptNeutral((InputPort *)source,impl,type,init);
754 //! Adapt a Neutral input port to a Corba output port
756 * \param inport : Neutral input port to adapt to Corba type type
757 * \param type : output port type
758 * \return an adaptated input port of type InputCorbaPort
760 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
761 TypeCode * type) throw (ConversionException)
763 // BEWARE : using the generic check
764 if(inport->edGetType()->isAdaptable(type))
766 //the output data is convertible to inport type
767 return new CorbaNeutral(inport);
769 //non convertible type
771 msg << "Cannot connect Corba output port with type: " << type->id() ;
772 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
774 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
776 throw ConversionException(msg.str());
779 //! Adapt a Neutral input port to a Python output port
781 * \param inport : input port to adapt to Python type type
782 * \param type : output port type
783 * \return an adaptated input port of type InputPyPort
785 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
786 TypeCode * type) throw (ConversionException)
788 // BEWARE : using the generic check
789 if(inport->edGetType()->isAdaptable(type))
792 return new PyNeutral(inport);
794 //non convertible type
796 msg << "Cannot connect Python output port with type: " << type->id() ;
797 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
799 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
801 throw ConversionException(msg.str());
804 //! Adapt a Neutral input port to a Xml output port
806 * \param inport : input port to adapt to Xml type type
807 * \param type : output port type
808 * \return an input port of type InputXmlPort
810 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
811 TypeCode * type) throw (ConversionException)
813 // BEWARE : using the generic check
814 if(inport->edGetType()->isAdaptable(type))
817 return new XmlNeutral(inport);
819 //non convertible type
821 msg << "Cannot connect Xml output port with type: " << type->id() ;
822 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
824 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
826 throw ConversionException(msg.str());
829 //! Adapt a Neutral input port to a C++ output port
831 * \param inport : input port to adapt to C++ type type
832 * \param type : output port type
833 * \return an input port of type InputCppPort
835 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
836 TypeCode * type) throw (ConversionException)
838 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
839 if(isAdaptableNeutralCpp(type,inport->edGetType()))
842 return new CppNeutral(inport);
844 //non convertible type
846 msg << "Cannot connect Cpp output port with type: " << type->id() ;
847 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
849 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
851 throw ConversionException(msg.str());
854 //! Adapt a Neutral input port to connect it to an output port with a given implementation
856 * \param source : Neutral input port to adapt to implementation impl and type type
857 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
858 * \param type : output port supported type
859 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
860 * \return the adaptated port
862 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
863 const std::string& impl,
864 TypeCode * type,bool init) throw (ConversionException)
866 if(impl == CppNode::IMPL_NAME)
868 return adaptNeutralToCpp(source,type);
870 else if(impl == PythonNode::IMPL_NAME)
872 return adaptNeutralToPython(source,type);
874 else if(impl == CORBANode::IMPL_NAME)
876 return adaptNeutralToCorba(source,type);
878 else if(impl == XmlNode::IMPL_NAME )
880 return adaptNeutralToXml(source,type);
882 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
885 return new NeutralInit(source);
887 return new ProxyPort(source);
890 msg << "Cannot connect InputPort : unknown implementation " << impl;
891 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
892 throw ConversionException(msg.str());
895 //! Adapt a XML input port to connect it to a CORBA output port
897 * \param inport : input port to adapt to CORBA type type
898 * \param type : type supported by output port
899 * \return an adaptator port of type InputCorbaPort
902 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
903 TypeCode * type) throw (ConversionException)
905 if(isAdaptableXmlCorba(type,inport->edGetType()))
907 //output type is convertible to input type
908 return new CorbaXml(inport);
910 //output type is not convertible
912 msg << "Cannot connect Corba output port with type: " << type->id() ;
913 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
915 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
917 throw ConversionException(msg.str());
920 //! Adapt a XML input port to a Python output port
922 * \param inport : input port to adapt to Python type type
923 * \param type : output port type
924 * \return an adaptated input port of type InputPyPort
926 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
927 TypeCode * type) throw (ConversionException)
929 if(inport->edGetType()->isAdaptable(type))
931 //the output data is convertible to inport type
932 return new PyXml(inport);
934 //non convertible type
936 msg << "Cannot connect Python output port with type: " << type->id() ;
937 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
939 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
941 throw ConversionException(msg.str());
944 //! Adapt a XML input port to a C++ output port
946 * \param inport : input port to adapt to C++ type type
947 * \param type : output port type
948 * \return an adaptated input port of type InputPyPort
950 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
951 TypeCode * type) throw (ConversionException)
953 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
954 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
955 if(type->isAdaptable(inport->edGetType()))
957 //the output data is convertible to inport type
958 return new CppXml(inport);
960 //non convertible type
962 msg << "Cannot connect Cpp output port with type: " << type->id() ;
963 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
965 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
967 throw ConversionException(msg.str());
970 //! Adapt a XML input port to a Neutral output port
972 * \param inport : input port to adapt to Neutral type type
973 * \param type : output port type
974 * \return an adaptated input port of type Neutralxxxx
976 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
977 TypeCode * type) throw (ConversionException)
979 if(inport->edGetType()->isAdaptable(type))
981 //the output data is convertible to inport type
982 return new NeutralXml(inport);
984 //non convertible type
986 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
987 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
988 throw ConversionException(msg.str());
991 //! Adapt a XML input port to a Xml output port
993 * \param inport : input port to adapt to Xml type type
994 * \param type : output port type
995 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
996 * \return an adaptated input port of type Xmlxxxx
998 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
999 TypeCode * type,bool init) throw (ConversionException)
1002 return new ProxyPort(inport);
1004 if(inport->edGetType()->isAdaptable(type))
1005 return new ProxyPort(inport);
1008 msg << "Cannot connect Xml output port with type: " << type->id() ;
1009 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1011 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1013 throw ConversionException(msg.str());
1016 //! Adapt an Xml input port to an output port which implementation is given by impl
1018 * \param source : input port to adapt to implementation impl and type type
1019 * \param impl : output port implementation (C++, Python or Corba)
1020 * \param type : output port supported type
1021 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1022 * \return the adaptated port
1025 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1026 const std::string& impl,
1027 TypeCode * type,bool init) throw (ConversionException)
1029 if(impl == CORBANode::IMPL_NAME)
1031 return adaptXmlToCorba(source,type);
1033 else if(impl == PythonNode::IMPL_NAME)
1035 return adaptXmlToPython(source,type);
1037 else if(impl == CppNode::IMPL_NAME)
1039 return adaptXmlToCpp(source,type);
1041 else if(impl == XmlNode::IMPL_NAME )
1043 return adaptXmlToXml(source,type,init);
1045 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1047 return adaptXmlToNeutral(source,type);
1052 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1053 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1054 throw ConversionException(msg.str());
1059 //! Adapt a CORBA input port to a CORBA output port
1061 * \param inport : input port to adapt to CORBA outport data type
1062 * \param type : outport data type
1063 * \return an adaptator port of type InputCORBAPort
1065 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1066 TypeCode * type) throw (ConversionException)
1068 if(type->isA(inport->edGetType()))
1070 //types are compatible : no conversion
1071 //outport data type is more specific than inport required type
1072 //so the inport can be used safely
1073 return new ProxyPort(inport);
1075 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1077 //ouport data can be converted to inport data type
1078 return new CorbaCorba(inport);
1080 //outport data can not be converted
1082 msg << "Cannot connect Corba output port with type: " << type->id() ;
1083 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1085 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1087 throw ConversionException(msg.str());
1090 //! Adapt a CORBA input port to a Python output port
1092 * \param inport : input port to adapt to Python type type
1093 * \param type : outport data type
1094 * \return an adaptator port of type InputPyPort
1097 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1098 TypeCode * type) throw (ConversionException)
1100 if(inport->edGetType()->kind() == Double)
1102 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1104 else if(inport->edGetType()->kind() == Int)
1106 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1108 else if(inport->edGetType()->kind() == String)
1110 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1112 else if(inport->edGetType()->kind() == Bool)
1114 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1116 else if(inport->edGetType()->kind() == Objref )
1118 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1120 return new PyCorbaObjref(inport);
1125 msg << "Cannot connect Python output port with type: " << type->id() ;
1126 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1127 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1128 throw ConversionException(msg.str());
1131 else if(inport->edGetType()->kind() == Sequence)
1133 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1135 return new PyCorbaSequence(inport);
1140 msg << "Cannot convert this sequence type " ;
1141 msg << __FILE__ << ":" <<__LINE__;
1142 throw ConversionException(msg.str());
1145 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1147 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1149 return new PyCorbaStruct(inport);
1154 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1155 msg << __FILE__ << ":" <<__LINE__;
1156 throw ConversionException(msg.str());
1159 // Adaptation not possible
1161 msg << "Cannot connect Python output port with type: " << type->id() ;
1162 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1164 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1166 throw ConversionException(msg.str());
1169 //! Adapt a CORBA input port to connect it to a XML output port
1171 * \param inport : input port to adapt to Xml type type
1172 * \param type : type supported by output port
1173 * \return an adaptator port of type InputXmlPort
1176 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1177 TypeCode * type) throw (ConversionException)
1179 // BEWARE : using the generic check
1180 if(inport->edGetType()->isAdaptable(type))
1182 //output type is convertible to input type
1183 return new XmlCorba(inport);
1185 //output type is not convertible
1187 msg << "Cannot connect Xml output port with type: " << type->id() ;
1188 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1190 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1192 throw ConversionException(msg.str());
1195 //! Adapt a CORBA input port to a C++ output port
1197 * \param inport : input port to adapt to C++ type type
1198 * \param type : outport data type
1199 * \return an adaptator port of type InputCPPPort
1202 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1203 TypeCode * type) throw (ConversionException)
1205 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1206 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1208 //output type is convertible to input type
1209 return new CppCorba(inport);
1211 //output type is not convertible
1213 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1214 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1216 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1218 throw ConversionException(msg.str());
1221 //! Adapt a CORBA input port to a neutral data
1223 * \param inport : InputPort to adapt to Neutral type type
1224 * \param type : outport data type
1225 * \return an adaptator port of type Neutralxxxx
1228 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1229 TypeCode * type) throw (ConversionException)
1231 if(inport->edGetType()->kind() == Double)
1233 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1235 else if(inport->edGetType()->kind() == Int)
1237 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1239 else if(inport->edGetType()->kind() == String)
1241 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1243 else if(inport->edGetType()->kind() == Bool)
1245 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1247 else if(inport->edGetType()->kind() == Objref)
1249 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1251 else if(inport->edGetType()->kind() == Sequence)
1253 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1254 return new NeutralCorbaSequence(inport);
1258 msg << "Cannot convert this sequence type " ;
1259 msg << __FILE__ << ":" <<__LINE__;
1260 throw ConversionException(msg.str());
1263 else if(inport->edGetType()->kind() == Struct)
1265 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1268 // Adaptation not possible
1270 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1271 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1273 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1275 throw ConversionException(msg.str());
1278 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1280 * \param source : input port to adapt to implementation impl and type type
1281 * \param impl : output port implementation (C++, Python or Corba)
1282 * \param type : outport data type
1283 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1284 * \return an adaptator port which type depends on impl
1287 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1288 const std::string& impl,
1289 TypeCode * type,bool init) throw (ConversionException)
1291 if(impl == CppNode::IMPL_NAME)
1293 return adaptCorbaToCpp(source,type);
1295 else if(impl == PythonNode::IMPL_NAME)
1297 return adaptCorbaToPython(source,type);
1299 else if(impl == CORBANode::IMPL_NAME)
1302 return adaptCorbaToCorba(source,type);
1304 return adaptCorbaToCorba(source,type);
1306 else if(impl == XmlNode::IMPL_NAME )
1308 return adaptCorbaToXml(source,type);
1310 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1312 return adaptCorbaToNeutral(source,type);
1317 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1318 msg << __FILE__ << ":" <<__LINE__;
1319 throw ConversionException(msg.str());
1323 //! Adapt a Python input port to a Python output port
1325 * No need to make conversion or cast.
1326 * Only check, it's possible.
1327 * \param inport : InputPort to adapt to Python type type
1328 * \param type : outport data type
1329 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1330 * \return an adaptator port of type InputPyPort
1333 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1334 TypeCode * type,bool init) throw (ConversionException)
1337 return new PyInit(inport);
1339 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1341 //output data is convertible to input type
1342 //With python, no need to convert. Conversion will be done automatically
1343 //by the interpreter
1344 return new ProxyPort(inport);
1346 //output data is not convertible to input type
1348 msg << "Cannot connect Python output port with type: " << type->id() ;
1349 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1351 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1353 throw ConversionException(msg.str());
1356 //! Adapt a Python input port to a C++ output port
1358 * \param inport : InputPort to adapt to C++ type type
1359 * \param type : outport data type
1360 * \return an adaptator port of C++ type (InputCppPort)
1363 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1364 TypeCode * type) throw (ConversionException)
1366 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1367 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1369 //output type is convertible to input type
1370 return new CppPy(inport);
1372 //output type is not convertible
1374 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1375 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1377 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1379 throw ConversionException(msg.str());
1382 //! Adapt a Python input port to a Neutral data port
1384 * \param inport : InputPort to adapt to Neutral type type
1385 * \param type : outport data type
1386 * \return an adaptator port of Neutral type (Neutralxxxx)
1389 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1390 TypeCode * type) throw (ConversionException)
1392 if(inport->edGetType()->kind() == Double)
1394 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1396 else if(inport->edGetType()->kind() == Int)
1398 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1400 else if(inport->edGetType()->kind() == String)
1402 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1404 else if(inport->edGetType()->kind() == Bool)
1406 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1408 else if(inport->edGetType()->kind() == Objref)
1410 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1412 else if(inport->edGetType()->kind() == Sequence)
1414 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1415 return new NeutralPySequence(inport);
1419 msg << "Cannot convert this sequence type " ;
1420 msg << __FILE__ << ":" <<__LINE__;
1421 throw ConversionException(msg.str());
1424 else if(inport->edGetType()->kind() == Struct)
1426 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1429 // Adaptation not possible
1431 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1432 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1434 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1436 throw ConversionException(msg.str());
1439 //! Adapt a Python input port to a Corba output port
1441 * Always convert the data
1442 * \param inport : InputPort to adapt to Corba type type
1443 * \param type : outport data type
1444 * \return an adaptator port of Corba type (InputCorbaPort)
1447 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1448 TypeCode * type) throw (ConversionException)
1450 if(inport->edGetType()->kind() == Double)
1452 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1454 else if(inport->edGetType()->kind() == Int)
1456 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1458 else if(inport->edGetType()->kind() == String)
1460 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1462 else if(inport->edGetType()->kind() == Bool)
1464 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1466 else if(inport->edGetType()->kind() == Objref)
1468 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1470 return new CorbaPyObjref(inport);
1475 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1476 msg << " " << __FILE__ << ":" <<__LINE__;
1477 throw ConversionException(msg.str());
1480 else if(inport->edGetType()->kind() == Sequence)
1482 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1484 return new CorbaPySequence(inport);
1489 msg << "Cannot convert this sequence type " ;
1490 msg << __FILE__ << ":" <<__LINE__;
1491 throw ConversionException(msg.str());
1494 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1496 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1498 return new CorbaPyStruct(inport);
1503 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1504 msg << " " << __FILE__ << ":" <<__LINE__;
1505 throw ConversionException(msg.str());
1508 // Adaptation not possible
1510 msg << "Cannot connect Corba output port with type: " << type->id() ;
1511 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1513 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1515 throw ConversionException(msg.str());
1518 //! Adapt a Python input port to a Xml output port
1520 * \param inport : input port to adapt to Xml type type
1521 * \param type : output port type
1522 * \return an input port of type InputXmlPort
1525 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1526 TypeCode * type) throw (ConversionException)
1528 // BEWARE : using the generic check
1529 if(inport->edGetType()->isAdaptable(type))
1532 return new XmlPython(inport);
1534 //non convertible type
1536 msg << "Cannot connect Xml output port with type: " << type->id() ;
1537 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1539 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1541 throw ConversionException(msg.str());
1544 //! Adapt a Python input port to an output port with a given implementation
1546 * \param source : input port to adapt to implementation impl and type type
1547 * \param impl : output port implementation (C++, Python or Corba)
1548 * \param type : output port type
1549 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1550 * \return adaptated input port
1553 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1554 const std::string& impl,
1555 TypeCode * type,bool init) throw (ConversionException)
1557 if(impl == CppNode::IMPL_NAME)
1559 return adaptPythonToCpp(source,type);
1561 else if(impl == PythonNode::IMPL_NAME)
1563 return adaptPythonToPython(source,type,init);
1565 else if(impl == CORBANode::IMPL_NAME)
1567 return adaptPythonToCorba(source,type);
1569 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1571 return adaptPythonToNeutral(source,type);
1573 else if(impl == XmlNode::IMPL_NAME)
1575 return adaptPythonToXml(source,type);
1580 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1581 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1582 throw ConversionException(msg.str());
1587 //! Adapt a C++ input port to connect it to a CORBA output port
1589 * \param inport : input port to adapt to CORBA type type
1590 * \param type : type supported by output port
1591 * \return an adaptator port of type InputCorbaPort
1594 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1595 TypeCode * type) throw (ConversionException)
1597 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1598 if(isAdaptableCppCorba(type,inport->edGetType()))
1600 //output type is convertible to input type
1601 return new CorbaCpp(inport);
1603 //output type is not convertible
1605 msg << "Cannot connect Corba output port with type: " << type->id() ;
1606 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1608 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1610 throw ConversionException(msg.str());
1613 //! Adapt a C++ input port to a Python output port
1615 * \param inport : input port to adapt to Python type type
1616 * \param type : output port type
1617 * \return an adaptated input port of type InputPyPort
1619 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1620 TypeCode * type) throw (ConversionException)
1622 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1623 if(isAdaptableCppPyObject(type,inport->edGetType()))
1625 //output type is convertible to input type
1626 return new PyCpp(inport);
1628 //output type is not convertible
1630 msg << "Cannot connect Python output port with type: " << type->id() ;
1631 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1633 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1635 throw ConversionException(msg.str());
1638 //! Adapt a C++ input port to a C++ output port
1640 * \param inport : input port to adapt to C++ type type
1641 * \param type : output port type
1642 * \return an adaptated input port of type InputPyPort
1644 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1645 TypeCode * type) throw (ConversionException)
1647 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1648 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1649 if(type->isAdaptable(inport->edGetType()))
1651 //the output data is convertible to inport type
1652 return new CppCpp(inport);
1654 //non convertible type
1656 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1657 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1659 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1661 throw ConversionException(msg.str());
1664 //! Adapt a C++ input port to a Neutral output port
1666 * \param inport : input port to adapt to C++ type type
1667 * \param type : output port type
1668 * \return an adaptated input port of type InputPyPort
1670 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1671 TypeCode * type) throw (ConversionException)
1673 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1674 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1675 if(type->isAdaptable(inport->edGetType()))
1677 //the output data is convertible to inport type
1678 return new NeutralCpp(inport);
1680 //non convertible type
1682 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1683 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1685 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1687 throw ConversionException(msg.str());
1690 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1691 TypeCode * type) throw (ConversionException)
1693 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1694 if(isAdaptableCppXml(type,inport->edGetType()))
1697 return new XmlCpp(inport);
1699 //non convertible type
1701 msg << "Cannot connect Xml output port with type: " << type->id() ;
1702 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1704 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1706 throw ConversionException(msg.str());
1709 //! Adapt a C++ input port to connect it to an output port with a given implementation
1711 * \param source : input port to adapt to implementation impl and type type
1712 * \param impl : output port implementation (C++, Python or Corba)
1713 * \param type : output port supported type
1714 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1715 * \return the adaptated port
1718 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1719 const std::string& impl,
1720 TypeCode * type,bool init) throw (ConversionException)
1722 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1723 if(impl == CORBANode::IMPL_NAME)
1725 return adaptCppToCorba(source,type);
1727 else if(impl == PythonNode::IMPL_NAME)
1729 return adaptCppToPython(source,type);
1731 else if(impl == XmlNode::IMPL_NAME)
1733 return adaptCppToXml(source,type);
1735 else if(impl == CppNode::IMPL_NAME)
1737 return adaptCppToCpp(source, type);
1739 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1741 return adaptCppToNeutral(source, type);
1746 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1747 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1748 throw ConversionException(msg.str());
1752 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1753 // const InputPort* inputPort)
1755 // bool result=true;
1759 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1764 PyObject * RuntimeSALOME::getPyOrb()
1769 PyObject * RuntimeSALOME::getBuiltins()
1774 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1779 PyObject * RuntimeSALOME::get_omnipy()
1784 omniORBpyAPI* RuntimeSALOME::getApi()
1789 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1792 return (void *)convertNeutralPyObject(type,data);
1796 return (void *)Py_None;
1800 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1805 ob=convertNeutralPyObject(type,data);
1806 std::string s=convertPyObjectToString(ob);
1808 // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1809 // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1810 // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1811 // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1812 // feel free to change this code.
1813 PyGILState_STATE gstate = PyGILState_Ensure();
1815 PyGILState_Release(gstate);
1824 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1826 return YACS::ENGINE::convertPyObjectToString(ob);
1829 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1834 PyGILState_STATE gstate = PyGILState_Ensure();
1835 mainmod = PyImport_AddModule("__main__");
1836 globals = PyModule_GetDict(mainmod);
1837 PyObject* d = PyDict_New();
1838 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1839 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1845 PyObject* new_stderr = newPyStdOut(error);
1846 PySys_SetObject((char *)"stderr", new_stderr);
1848 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1849 Py_DECREF(new_stderr);
1850 PyGILState_Release(gstate);
1851 throw Exception(error);
1853 PyGILState_Release(gstate);