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"
60 #include "PythonNode.hxx"
61 #include "CORBANode.hxx"
62 #include "XMLNode.hxx"
63 #include "CppNode.hxx"
64 #include "PresetNode.hxx"
65 #include "OutNode.hxx"
66 #include "StudyNodes.hxx"
67 #include "SalomePythonNode.hxx"
68 #include "DistributedPythonNode.hxx"
71 #include "CORBACORBAConv.hxx"
72 #include "CORBAPythonConv.hxx"
73 #include "CORBAXMLConv.hxx"
74 #include "CORBACppConv.hxx"
75 #include "CORBANeutralConv.hxx"
77 #include "TypeConversions.hxx"
79 #include "PythonCORBAConv.hxx"
80 #include "PythonXMLConv.hxx"
81 #include "PythonCppConv.hxx"
82 #include "PythonNeutralConv.hxx"
83 #include "PythonInitConv.hxx"
86 #include "NeutralCORBAConv.hxx"
87 #include "NeutralPythonConv.hxx"
88 #include "NeutralXMLConv.hxx"
89 #include "NeutralCppConv.hxx"
90 #include "NeutralInitConv.hxx"
93 #include "CppCORBAConv.hxx"
94 #include "CppPythonConv.hxx"
95 #include "CppXMLConv.hxx"
96 #include "CppCppConv.hxx"
97 #include "CppNeutralConv.hxx"
100 #include "XMLCORBAConv.hxx"
101 #include "XMLPythonConv.hxx"
102 #include "XMLCppConv.hxx"
103 #include "XMLNeutralConv.hxx"
105 //Calcium specific ports
106 #include "CalStreamPort.hxx"
109 #include "SALOME_NamingService.hxx"
110 #include "SALOME_LifeCycleCORBA.hxx"
113 #include <libxml/parser.h>
114 #include <omniORB4/CORBA.h>
120 #include "YacsTrace.hxx"
123 using namespace YACS::ENGINE;
125 void RuntimeSALOME::setRuntime(long flags, int argc, char* argv[]) // singleton creation (not thread safe!)
127 if (! Runtime::_singleton)
129 RuntimeSALOME* r=new RuntimeSALOME(flags, argc, argv);
130 Runtime::_singleton = r;
133 DEBTRACE("RuntimeSALOME::setRuntime() done !");
136 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
138 YASSERT(Runtime::_singleton);
139 return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
143 * Singleton creation, initialize converter map
146 RuntimeSALOME::RuntimeSALOME()
151 void RuntimeSALOME::initBuiltins()
153 //Fill the builtin catalog with nodes specific to the runtime
154 std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
155 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
156 std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
157 std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
158 nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
159 nodeMap["PyScript"]=new PythonNode("PyScript");
160 nodeMap["CORBANode"]=new CORBANode("CORBANode");
161 nodeMap["XmlNode"]=new XmlNode("XmlNode");
162 nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
163 nodeMap["CppNode"]=new CppNode("CppNode");
164 nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
165 nodeMap["PresetNode"]=new PresetNode("PresetNode");
166 nodeMap["OutNode"]=new OutNode("OutNode");
167 nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
168 nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
169 composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
170 typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
171 typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
172 typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
173 typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
174 typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
175 typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
176 typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
177 typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
178 std::list<TypeCodeObjref *> ltc;
179 typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
180 ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
181 t->addMember("ref",_tc_string);
182 typeMap["dataref"]= t;
185 RuntimeSALOME::RuntimeSALOME(long flags, int argc, char* argv[])
187 // If all flags (apart the IsPyExt flags) are unset, force them to true
188 if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
189 flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
190 + RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
192 // Salome Nodes implies Corba Nodes
193 if (flags & RuntimeSALOME::UseSalome)
194 flags |= RuntimeSALOME::UseCorba;
196 // Corba Nodes implies Python Nodes
197 if (flags & RuntimeSALOME::UseCorba)
198 flags |= RuntimeSALOME::UsePython;
200 _useCorba = flags & RuntimeSALOME::UseCorba;
201 _usePython = flags & RuntimeSALOME::UsePython;
202 _useCpp = flags & RuntimeSALOME::UseCpp;
203 _useXml = flags & RuntimeSALOME::UseXml;
208 if (_useCpp) _setOfImplementation.insert(CppNode::IMPL_NAME);
209 if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
210 if (_useCorba) _setOfImplementation.insert(CORBANode::IMPL_NAME);
211 if (_useXml) _setOfImplementation.insert(XmlNode::IMPL_NAME);
212 init(flags, argc, argv);
215 RuntimeSALOME::~RuntimeSALOME()
217 DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
218 // destroy catalog loader prototypes
219 std::map<std::string, CatalogLoader*>::const_iterator pt;
220 for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
226 //! CORBA and Python initialization
228 * \param flags contains several bits
229 * bit0 (ispyext) true when method is called from Python
230 * (Python initialization must not be done!)
231 * bit1 (UsePython) true if python nodes are needed
232 * bit1 (UseCorba) true if CORBA nodes are needed
233 * bit1 (UseXml) true if python nodes are needed
234 * bit1 (UseCpp) true if C++ nodes are needed
235 * bit1 (UseSalome) true if Salome nodes are needed
236 * \param argc number of command line arguments (used to initialize the Python interpreter)
237 * \param argv command line arguments (used to initialize the Python interpreter)
241 void RuntimeSALOME::init(long flags, int argc, char* argv[])
243 bool ispyext = flags & RuntimeSALOME::IsPyExt;
246 PortableServer::POA_var root_poa;
247 PortableServer::POAManager_var pman;
248 CORBA::Object_var obj;
249 int nbargs = 0; char **args = 0;
250 _orb = CORBA::ORB_init (nbargs, args);
251 obj = _orb->resolve_initial_references("RootPOA");
252 root_poa = PortableServer::POA::_narrow(obj);
253 pman = root_poa->the_POAManager();
257 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
259 obj = _orb->resolve_initial_references("DynAnyFactory");
260 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
265 DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
267 // Initialize Python interpreter in embedded mode
268 if (!Py_IsInitialized())
270 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
273 Py_InitializeEx(0); // do not install signal handlers
275 if (argc > 0 && argv != NULL)
276 PySys_SetArgv(argc, argv);
281 char defaultName[] = "SALOME_YACS_RUNTIME";
282 pyArgv[0] = defaultName;
283 PySys_SetArgv(pyArgc, pyArgv);
285 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
286 PyEval_SaveThread(); /* Release the thread state */
287 //here we do not have the Global Interpreter Lock
290 PyObject *mainmod,*pyapi,*res ;
292 PyGILState_STATE gstate;
293 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
295 mainmod = PyImport_AddModule("__main__");
296 globals = PyModule_GetDict(mainmod);
297 /* globals is a borrowed reference */
299 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
301 PyObject *bimod = PyImport_ImportModule("__builtin__");
302 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
303 Py_FatalError("can't add __builtins__ to __main__");
307 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
313 _omnipy = PyImport_ImportModule((char*)"_omnipy");
317 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
320 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
325 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
328 res=PyRun_String("\n"
329 "from math import *\n"
331 "sys.path.insert(0,'.')\n"
332 "from omniORB import CORBA\n"
333 "from omniORB import any\n"
334 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
335 "#print sys.getrefcount(orb)\n"
341 Py_file_input,globals,globals );
349 _pyorb = PyDict_GetItemString(globals,"orb");
350 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
353 pyany = PyDict_GetItemString(globals,"any");
354 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
357 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
361 PyGILState_Release(gstate); // Release the Global Interpreter Lock
365 // initialize the catalogLoaderFactory map with the session one
366 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
370 void RuntimeSALOME::fini()
374 PyGILState_STATE gstate = PyGILState_Ensure();
376 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
378 PyObject *mainmod, *globals;
379 mainmod = PyImport_AddModule("__main__");
380 globals = PyModule_GetDict(mainmod);
384 res=PyRun_String("orb.destroy()\n"
386 Py_file_input,globals,globals );
392 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
393 delete nodeMap["PyFunction"];
394 delete nodeMap["PyScript"];
395 delete nodeMap["SalomePythonNode"];
396 nodeMap.erase("PyFunction");
397 nodeMap.erase("PyScript");
398 nodeMap.erase("SalomePythonNode");
402 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
410 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
417 std::string RuntimeSALOME::getVersion() const
419 #ifdef YACS_DEVELOPMENT
420 return CORBA::string_dup(YACS_VERSION_STR"dev");
422 return CORBA::string_dup(YACS_VERSION_STR);
426 Proc* RuntimeSALOME::createProc(const std::string& name)
428 return new SalomeProc(name);
431 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
432 std::list<TypeCodeObjref *> ltc)
435 if(id == "") myName = "IDL:" + name + ":1.0";
437 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
440 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
441 const std::string& name,
444 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
447 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
450 if(id == "") myName = "IDL:" + name + ":1.0";
452 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
455 Bloc* RuntimeSALOME::createBloc(const std::string& name)
457 return new Bloc(name);
460 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
462 return new WhileLoop(name);
465 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
467 return new ForLoop(name);
470 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
471 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
473 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
474 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
475 ol->edGetNbOfBranchesPort()->edInit(1);
479 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
484 node = new PresetNode(name);
487 else if(kind == "study" )
489 return new StudyInNode(name);
491 std::string msg="DataNode kind ("+kind+") unknown";
492 throw Exception(msg);
495 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
499 return new OutNode(name);
501 else if(kind == "study" )
503 return new StudyOutNode(name);
506 std::string msg="OutDataNode kind ("+kind+") unknown";
507 throw Exception(msg);
510 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
512 InlineFuncNode* node;
513 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
515 node = new PyFuncNode(name);
518 if(kind == DistributedPythonNode::KIND)
519 return new DistributedPythonNode(name);
520 std::string msg="FuncNode kind ("+kind+") unknown";
521 throw Exception(msg);
524 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
527 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
529 node = new PythonNode(name);
532 std::string msg="ScriptNode kind ("+kind+") unknown";
533 throw Exception(msg);
536 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
539 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
541 node = new CORBANode(name);
544 else if(kind == XmlNode::KIND)
546 node = new XmlNode(name);
549 std::string msg="RefNode kind ("+kind+") unknown";
550 throw Exception(msg);
553 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
556 if(kind == "" || kind == SalomeNode::KIND )
558 node=new SalomeNode(name);
561 else if (kind == CppNode::KIND)
563 node = new CppNode(name);
566 std::string msg="CompoNode kind ("+kind+") unknown";
567 throw Exception(msg);
570 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
572 if(kind == "" || kind == SalomeNode::KIND )
573 return new SalomePythonNode(name);
574 std::string msg="CompoNode kind ("+kind+") unknown";
575 throw Exception(msg);
578 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
579 const std::string& kind)
581 ComponentInstance* compo;
582 if(kind == "" || kind == SalomeComponent::KIND)
583 return new SalomeComponent(name);
584 else if(kind == CORBAComponent::KIND)
585 return new CORBAComponent(name);
586 else if(kind == SalomePythonComponent::KIND)
587 return new SalomePythonComponent(name);
588 else if (kind == CppComponent::KIND)
589 return new CppComponent(name);
590 std::string msg="Component Instance kind ("+kind+") unknown";
591 throw Exception(msg);
594 Container *RuntimeSALOME::createContainer(const std::string& kind)
596 if(kind == "" || kind == SalomeComponent::KIND)
597 return new SalomeContainer;
598 else if (kind == CppComponent::KIND)
599 return new CppContainer;
600 std::string msg="Container kind ("+kind+") unknown";
601 throw Exception(msg);
604 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
605 const std::string& impl,
609 if(impl == CppNode::IMPL_NAME)
611 return new InputCppPort(name, node, type);
613 else if(impl == PythonNode::IMPL_NAME)
615 return new InputPyPort(name, node, type);
617 else if(impl == CORBANode::IMPL_NAME)
619 return new InputCorbaPort(name, node, type);
621 else if(impl == XmlNode::IMPL_NAME)
623 return new InputXmlPort(name, node, type);
628 msg << "Cannot create " << impl << " InputPort" ;
629 msg << " ("__FILE__ << ":" << __LINE__ << ")";
630 throw Exception(msg.str());
634 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
635 const std::string& impl,
639 if(impl == CppNode::IMPL_NAME)
641 return new OutputCppPort(name, node, type);
643 else if(impl == PythonNode::IMPL_NAME)
645 return new OutputPyPort(name, node, type);
647 else if(impl == CORBANode::IMPL_NAME)
649 return new OutputCorbaPort(name, node, type);
651 else if(impl == XmlNode::IMPL_NAME)
653 return new OutputXmlPort(name, node, type);
658 msg << "Cannot create " << impl << " OutputPort" ;
659 msg << " ("__FILE__ << ":" << __LINE__ << ")";
660 throw Exception(msg.str());
664 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
665 Node *node,TypeCode *type)
667 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
668 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
670 return new InputCalStreamPort(name,node,type);
674 return new InputDataStreamPort(name,node,type);
678 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
679 Node *node,TypeCode *type)
681 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
682 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
684 return new OutputCalStreamPort(name,node,type);
688 return new OutputDataStreamPort(name,node,type);
692 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
694 * \param source : InputPort to be adapted
695 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
696 * \param type : data type provided by the InputPort
697 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
699 * \return : adapted InputPort
701 InputPort* RuntimeSALOME::adapt(InputPort* source,
702 const std::string& impl,
703 TypeCode * type,bool init) throw (ConversionException)
705 string imp_source=source->getNode()->getImplementation();
706 if(imp_source == PythonNode::IMPL_NAME)
708 return adapt((InputPyPort*)source,impl,type,init);
710 else if(imp_source == CppNode::IMPL_NAME)
712 return adapt((InputCppPort*)source,impl,type,init);
714 else if(imp_source == CORBANode::IMPL_NAME)
716 return adapt((InputCorbaPort*)source,impl,type,init);
718 else if(imp_source == XmlNode::IMPL_NAME)
720 return adapt((InputXmlPort*)source,impl,type,init);
722 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
724 return adaptNeutral(source,impl,type,init);
729 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
730 msg << " ("__FILE__ << ":" << __LINE__ << ")";
731 throw ConversionException(msg.str());
735 //! Adapter function for InPropertyPort
737 * \param source : InPropertyPort to be adapted
738 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
739 * \param type : data type provided by the InPropertyPort
740 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
742 * \return : adapted InputPort
744 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
745 const std::string& impl,
746 TypeCode * type,bool init) throw (ConversionException)
748 return adaptNeutral((InputPort *)source,impl,type,init);
751 //! Adapt a Neutral input port to a Corba output port
753 * \param inport : Neutral input port to adapt to Corba type type
754 * \param type : output port type
755 * \return an adaptated input port of type InputCorbaPort
757 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
758 TypeCode * type) throw (ConversionException)
760 // BEWARE : using the generic check
761 if(inport->edGetType()->isAdaptable(type))
763 //the output data is convertible to inport type
764 return new CorbaNeutral(inport);
766 //non convertible type
768 msg << "Cannot connect Corba output port with type: " << type->id() ;
769 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
771 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
773 throw ConversionException(msg.str());
776 //! Adapt a Neutral input port to a Python output port
778 * \param inport : input port to adapt to Python type type
779 * \param type : output port type
780 * \return an adaptated input port of type InputPyPort
782 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
783 TypeCode * type) throw (ConversionException)
785 // BEWARE : using the generic check
786 if(inport->edGetType()->isAdaptable(type))
789 return new PyNeutral(inport);
791 //non convertible type
793 msg << "Cannot connect Python output port with type: " << type->id() ;
794 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
796 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
798 throw ConversionException(msg.str());
801 //! Adapt a Neutral input port to a Xml output port
803 * \param inport : input port to adapt to Xml type type
804 * \param type : output port type
805 * \return an input port of type InputXmlPort
807 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
808 TypeCode * type) throw (ConversionException)
810 // BEWARE : using the generic check
811 if(inport->edGetType()->isAdaptable(type))
814 return new XmlNeutral(inport);
816 //non convertible type
818 msg << "Cannot connect Xml output port with type: " << type->id() ;
819 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
821 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
823 throw ConversionException(msg.str());
826 //! Adapt a Neutral input port to a C++ output port
828 * \param inport : input port to adapt to C++ type type
829 * \param type : output port type
830 * \return an input port of type InputCppPort
832 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
833 TypeCode * type) throw (ConversionException)
835 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
836 if(isAdaptableNeutralCpp(type,inport->edGetType()))
839 return new CppNeutral(inport);
841 //non convertible type
843 msg << "Cannot connect Cpp output port with type: " << type->id() ;
844 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
846 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
848 throw ConversionException(msg.str());
851 //! Adapt a Neutral input port to connect it to an output port with a given implementation
853 * \param source : Neutral input port to adapt to implementation impl and type type
854 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
855 * \param type : output port supported type
856 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
857 * \return the adaptated port
859 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
860 const std::string& impl,
861 TypeCode * type,bool init) throw (ConversionException)
863 if(impl == CppNode::IMPL_NAME)
865 return adaptNeutralToCpp(source,type);
867 else if(impl == PythonNode::IMPL_NAME)
869 return adaptNeutralToPython(source,type);
871 else if(impl == CORBANode::IMPL_NAME)
873 return adaptNeutralToCorba(source,type);
875 else if(impl == XmlNode::IMPL_NAME )
877 return adaptNeutralToXml(source,type);
879 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
882 return new NeutralInit(source);
884 return new ProxyPort(source);
887 msg << "Cannot connect InputPort : unknown implementation " << impl;
888 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
889 throw ConversionException(msg.str());
892 //! Adapt a XML input port to connect it to a CORBA output port
894 * \param inport : input port to adapt to CORBA type type
895 * \param type : type supported by output port
896 * \return an adaptator port of type InputCorbaPort
899 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
900 TypeCode * type) throw (ConversionException)
902 if(isAdaptableXmlCorba(type,inport->edGetType()))
904 //output type is convertible to input type
905 return new CorbaXml(inport);
907 //output type is not convertible
909 msg << "Cannot connect Corba output port with type: " << type->id() ;
910 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
912 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
914 throw ConversionException(msg.str());
917 //! Adapt a XML input port to a Python output port
919 * \param inport : input port to adapt to Python type type
920 * \param type : output port type
921 * \return an adaptated input port of type InputPyPort
923 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
924 TypeCode * type) throw (ConversionException)
926 if(inport->edGetType()->isAdaptable(type))
928 //the output data is convertible to inport type
929 return new PyXml(inport);
931 //non convertible type
933 msg << "Cannot connect Python output port with type: " << type->id() ;
934 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
936 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
938 throw ConversionException(msg.str());
941 //! Adapt a XML input port to a C++ output port
943 * \param inport : input port to adapt to C++ type type
944 * \param type : output port type
945 * \return an adaptated input port of type InputPyPort
947 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
948 TypeCode * type) throw (ConversionException)
950 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
951 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
952 if(type->isAdaptable(inport->edGetType()))
954 //the output data is convertible to inport type
955 return new CppXml(inport);
957 //non convertible type
959 msg << "Cannot connect Cpp output port with type: " << type->id() ;
960 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
962 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
964 throw ConversionException(msg.str());
967 //! Adapt a XML input port to a Neutral output port
969 * \param inport : input port to adapt to Neutral type type
970 * \param type : output port type
971 * \return an adaptated input port of type Neutralxxxx
973 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
974 TypeCode * type) throw (ConversionException)
976 if(inport->edGetType()->isAdaptable(type))
978 //the output data is convertible to inport type
979 return new NeutralXml(inport);
981 //non convertible type
983 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
984 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
985 throw ConversionException(msg.str());
988 //! Adapt a XML input port to a Xml output port
990 * \param inport : input port to adapt to Xml type type
991 * \param type : output port type
992 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
993 * \return an adaptated input port of type Xmlxxxx
995 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
996 TypeCode * type,bool init) throw (ConversionException)
999 return new ProxyPort(inport);
1001 if(inport->edGetType()->isAdaptable(type))
1002 return new ProxyPort(inport);
1005 msg << "Cannot connect Xml output port with type: " << type->id() ;
1006 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1008 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1010 throw ConversionException(msg.str());
1013 //! Adapt an Xml input port to an output port which implementation is given by impl
1015 * \param source : input port to adapt to implementation impl and type type
1016 * \param impl : output port implementation (C++, Python or Corba)
1017 * \param type : output port supported type
1018 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1019 * \return the adaptated port
1022 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1023 const std::string& impl,
1024 TypeCode * type,bool init) throw (ConversionException)
1026 if(impl == CORBANode::IMPL_NAME)
1028 return adaptXmlToCorba(source,type);
1030 else if(impl == PythonNode::IMPL_NAME)
1032 return adaptXmlToPython(source,type);
1034 else if(impl == CppNode::IMPL_NAME)
1036 return adaptXmlToCpp(source,type);
1038 else if(impl == XmlNode::IMPL_NAME )
1040 return adaptXmlToXml(source,type,init);
1042 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1044 return adaptXmlToNeutral(source,type);
1049 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1050 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1051 throw ConversionException(msg.str());
1056 //! Adapt a CORBA input port to a CORBA output port
1058 * \param inport : input port to adapt to CORBA outport data type
1059 * \param type : outport data type
1060 * \return an adaptator port of type InputCORBAPort
1062 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1063 TypeCode * type) throw (ConversionException)
1065 if(type->isA(inport->edGetType()))
1067 //types are compatible : no conversion
1068 //outport data type is more specific than inport required type
1069 //so the inport can be used safely
1070 return new ProxyPort(inport);
1072 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1074 //ouport data can be converted to inport data type
1075 return new CorbaCorba(inport);
1077 //outport data can not be converted
1079 msg << "Cannot connect Corba output port with type: " << type->id() ;
1080 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1082 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1084 throw ConversionException(msg.str());
1087 //! Adapt a CORBA input port to a Python output port
1089 * \param inport : input port to adapt to Python type type
1090 * \param type : outport data type
1091 * \return an adaptator port of type InputPyPort
1094 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1095 TypeCode * type) throw (ConversionException)
1097 if(inport->edGetType()->kind() == Double)
1099 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1101 else if(inport->edGetType()->kind() == Int)
1103 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1105 else if(inport->edGetType()->kind() == String)
1107 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1109 else if(inport->edGetType()->kind() == Bool)
1111 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1113 else if(inport->edGetType()->kind() == Objref )
1115 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1117 return new PyCorbaObjref(inport);
1122 msg << "Cannot connect Python output port with type: " << type->id() ;
1123 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1124 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1125 throw ConversionException(msg.str());
1128 else if(inport->edGetType()->kind() == Sequence)
1130 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1132 return new PyCorbaSequence(inport);
1137 msg << "Cannot convert this sequence type " ;
1138 msg << __FILE__ << ":" <<__LINE__;
1139 throw ConversionException(msg.str());
1142 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1144 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1146 return new PyCorbaStruct(inport);
1151 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1152 msg << __FILE__ << ":" <<__LINE__;
1153 throw ConversionException(msg.str());
1156 // Adaptation not possible
1158 msg << "Cannot connect Python output port with type: " << type->id() ;
1159 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1161 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1163 throw ConversionException(msg.str());
1166 //! Adapt a CORBA input port to connect it to a XML output port
1168 * \param inport : input port to adapt to Xml type type
1169 * \param type : type supported by output port
1170 * \return an adaptator port of type InputXmlPort
1173 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1174 TypeCode * type) throw (ConversionException)
1176 // BEWARE : using the generic check
1177 if(inport->edGetType()->isAdaptable(type))
1179 //output type is convertible to input type
1180 return new XmlCorba(inport);
1182 //output type is not convertible
1184 msg << "Cannot connect Xml output port with type: " << type->id() ;
1185 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1187 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1189 throw ConversionException(msg.str());
1192 //! Adapt a CORBA input port to a C++ output port
1194 * \param inport : input port to adapt to C++ type type
1195 * \param type : outport data type
1196 * \return an adaptator port of type InputCPPPort
1199 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1200 TypeCode * type) throw (ConversionException)
1202 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1203 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1205 //output type is convertible to input type
1206 return new CppCorba(inport);
1208 //output type is not convertible
1210 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1211 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1213 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1215 throw ConversionException(msg.str());
1218 //! Adapt a CORBA input port to a neutral data
1220 * \param inport : InputPort to adapt to Neutral type type
1221 * \param type : outport data type
1222 * \return an adaptator port of type Neutralxxxx
1225 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1226 TypeCode * type) throw (ConversionException)
1228 if(inport->edGetType()->kind() == Double)
1230 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1232 else if(inport->edGetType()->kind() == Int)
1234 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1236 else if(inport->edGetType()->kind() == String)
1238 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1240 else if(inport->edGetType()->kind() == Bool)
1242 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1244 else if(inport->edGetType()->kind() == Objref)
1246 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1248 else if(inport->edGetType()->kind() == Sequence)
1250 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1251 return new NeutralCorbaSequence(inport);
1255 msg << "Cannot convert this sequence type " ;
1256 msg << __FILE__ << ":" <<__LINE__;
1257 throw ConversionException(msg.str());
1260 else if(inport->edGetType()->kind() == Struct)
1262 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1265 // Adaptation not possible
1267 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1268 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1270 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1272 throw ConversionException(msg.str());
1275 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1277 * \param source : input port to adapt to implementation impl and type type
1278 * \param impl : output port implementation (C++, Python or Corba)
1279 * \param type : outport data type
1280 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1281 * \return an adaptator port which type depends on impl
1284 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1285 const std::string& impl,
1286 TypeCode * type,bool init) throw (ConversionException)
1288 if(impl == CppNode::IMPL_NAME)
1290 return adaptCorbaToCpp(source,type);
1292 else if(impl == PythonNode::IMPL_NAME)
1294 return adaptCorbaToPython(source,type);
1296 else if(impl == CORBANode::IMPL_NAME)
1299 return adaptCorbaToCorba(source,type);
1301 return adaptCorbaToCorba(source,type);
1303 else if(impl == XmlNode::IMPL_NAME )
1305 return adaptCorbaToXml(source,type);
1307 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1309 return adaptCorbaToNeutral(source,type);
1314 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1315 msg << __FILE__ << ":" <<__LINE__;
1316 throw ConversionException(msg.str());
1320 //! Adapt a Python input port to a Python output port
1322 * No need to make conversion or cast.
1323 * Only check, it's possible.
1324 * \param inport : InputPort to adapt to Python type type
1325 * \param type : outport data type
1326 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1327 * \return an adaptator port of type InputPyPort
1330 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1331 TypeCode * type,bool init) throw (ConversionException)
1334 return new PyInit(inport);
1336 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1338 //output data is convertible to input type
1339 //With python, no need to convert. Conversion will be done automatically
1340 //by the interpreter
1341 return new ProxyPort(inport);
1343 //output data is not convertible to input type
1345 msg << "Cannot connect Python output port with type: " << type->id() ;
1346 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1348 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1350 throw ConversionException(msg.str());
1353 //! Adapt a Python input port to a C++ output port
1355 * \param inport : InputPort to adapt to C++ type type
1356 * \param type : outport data type
1357 * \return an adaptator port of C++ type (InputCppPort)
1360 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1361 TypeCode * type) throw (ConversionException)
1363 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1364 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1366 //output type is convertible to input type
1367 return new CppPy(inport);
1369 //output type is not convertible
1371 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1372 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1374 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1376 throw ConversionException(msg.str());
1379 //! Adapt a Python input port to a Neutral data port
1381 * \param inport : InputPort to adapt to Neutral type type
1382 * \param type : outport data type
1383 * \return an adaptator port of Neutral type (Neutralxxxx)
1386 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1387 TypeCode * type) throw (ConversionException)
1389 if(inport->edGetType()->kind() == Double)
1391 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1393 else if(inport->edGetType()->kind() == Int)
1395 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1397 else if(inport->edGetType()->kind() == String)
1399 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1401 else if(inport->edGetType()->kind() == Bool)
1403 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1405 else if(inport->edGetType()->kind() == Objref)
1407 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1409 else if(inport->edGetType()->kind() == Sequence)
1411 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1412 return new NeutralPySequence(inport);
1416 msg << "Cannot convert this sequence type " ;
1417 msg << __FILE__ << ":" <<__LINE__;
1418 throw ConversionException(msg.str());
1421 else if(inport->edGetType()->kind() == Struct)
1423 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1426 // Adaptation not possible
1428 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1429 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1431 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1433 throw ConversionException(msg.str());
1436 //! Adapt a Python input port to a Corba output port
1438 * Always convert the data
1439 * \param inport : InputPort to adapt to Corba type type
1440 * \param type : outport data type
1441 * \return an adaptator port of Corba type (InputCorbaPort)
1444 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1445 TypeCode * type) throw (ConversionException)
1447 if(inport->edGetType()->kind() == Double)
1449 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1451 else if(inport->edGetType()->kind() == Int)
1453 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1455 else if(inport->edGetType()->kind() == String)
1457 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1459 else if(inport->edGetType()->kind() == Bool)
1461 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1463 else if(inport->edGetType()->kind() == Objref)
1465 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1467 return new CorbaPyObjref(inport);
1472 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1473 msg << " " << __FILE__ << ":" <<__LINE__;
1474 throw ConversionException(msg.str());
1477 else if(inport->edGetType()->kind() == Sequence)
1479 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1481 return new CorbaPySequence(inport);
1486 msg << "Cannot convert this sequence type " ;
1487 msg << __FILE__ << ":" <<__LINE__;
1488 throw ConversionException(msg.str());
1491 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1493 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1495 return new CorbaPyStruct(inport);
1500 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1501 msg << " " << __FILE__ << ":" <<__LINE__;
1502 throw ConversionException(msg.str());
1505 // Adaptation not possible
1507 msg << "Cannot connect Corba output port with type: " << type->id() ;
1508 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1510 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1512 throw ConversionException(msg.str());
1515 //! Adapt a Python input port to a Xml output port
1517 * \param inport : input port to adapt to Xml type type
1518 * \param type : output port type
1519 * \return an input port of type InputXmlPort
1522 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1523 TypeCode * type) throw (ConversionException)
1525 // BEWARE : using the generic check
1526 if(inport->edGetType()->isAdaptable(type))
1529 return new XmlPython(inport);
1531 //non convertible type
1533 msg << "Cannot connect Xml output port with type: " << type->id() ;
1534 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1536 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1538 throw ConversionException(msg.str());
1541 //! Adapt a Python input port to an output port with a given implementation
1543 * \param source : input port to adapt to implementation impl and type type
1544 * \param impl : output port implementation (C++, Python or Corba)
1545 * \param type : output port type
1546 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1547 * \return adaptated input port
1550 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1551 const std::string& impl,
1552 TypeCode * type,bool init) throw (ConversionException)
1554 if(impl == CppNode::IMPL_NAME)
1556 return adaptPythonToCpp(source,type);
1558 else if(impl == PythonNode::IMPL_NAME)
1560 return adaptPythonToPython(source,type,init);
1562 else if(impl == CORBANode::IMPL_NAME)
1564 return adaptPythonToCorba(source,type);
1566 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1568 return adaptPythonToNeutral(source,type);
1570 else if(impl == XmlNode::IMPL_NAME)
1572 return adaptPythonToXml(source,type);
1577 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1578 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1579 throw ConversionException(msg.str());
1584 //! Adapt a C++ input port to connect it to a CORBA output port
1586 * \param inport : input port to adapt to CORBA type type
1587 * \param type : type supported by output port
1588 * \return an adaptator port of type InputCorbaPort
1591 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1592 TypeCode * type) throw (ConversionException)
1594 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1595 if(isAdaptableCppCorba(type,inport->edGetType()))
1597 //output type is convertible to input type
1598 return new CorbaCpp(inport);
1600 //output type is not convertible
1602 msg << "Cannot connect Corba output port with type: " << type->id() ;
1603 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1605 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1607 throw ConversionException(msg.str());
1610 //! Adapt a C++ input port to a Python output port
1612 * \param inport : input port to adapt to Python type type
1613 * \param type : output port type
1614 * \return an adaptated input port of type InputPyPort
1616 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1617 TypeCode * type) throw (ConversionException)
1619 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1620 if(isAdaptableCppPyObject(type,inport->edGetType()))
1622 //output type is convertible to input type
1623 return new PyCpp(inport);
1625 //output type is not convertible
1627 msg << "Cannot connect Python output port with type: " << type->id() ;
1628 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1630 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1632 throw ConversionException(msg.str());
1635 //! Adapt a C++ input port to a C++ output port
1637 * \param inport : input port to adapt to C++ type type
1638 * \param type : output port type
1639 * \return an adaptated input port of type InputPyPort
1641 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1642 TypeCode * type) throw (ConversionException)
1644 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1645 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1646 if(type->isAdaptable(inport->edGetType()))
1648 //the output data is convertible to inport type
1649 return new CppCpp(inport);
1651 //non convertible type
1653 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1654 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1656 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1658 throw ConversionException(msg.str());
1661 //! Adapt a C++ input port to a Neutral output port
1663 * \param inport : input port to adapt to C++ type type
1664 * \param type : output port type
1665 * \return an adaptated input port of type InputPyPort
1667 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1668 TypeCode * type) throw (ConversionException)
1670 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1671 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1672 if(type->isAdaptable(inport->edGetType()))
1674 //the output data is convertible to inport type
1675 return new NeutralCpp(inport);
1677 //non convertible type
1679 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1680 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1682 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1684 throw ConversionException(msg.str());
1687 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1688 TypeCode * type) throw (ConversionException)
1690 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1691 if(isAdaptableCppXml(type,inport->edGetType()))
1694 return new XmlCpp(inport);
1696 //non convertible type
1698 msg << "Cannot connect Xml output port with type: " << type->id() ;
1699 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1701 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1703 throw ConversionException(msg.str());
1706 //! Adapt a C++ input port to connect it to an output port with a given implementation
1708 * \param source : input port to adapt to implementation impl and type type
1709 * \param impl : output port implementation (C++, Python or Corba)
1710 * \param type : output port supported type
1711 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1712 * \return the adaptated port
1715 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1716 const std::string& impl,
1717 TypeCode * type,bool init) throw (ConversionException)
1719 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1720 if(impl == CORBANode::IMPL_NAME)
1722 return adaptCppToCorba(source,type);
1724 else if(impl == PythonNode::IMPL_NAME)
1726 return adaptCppToPython(source,type);
1728 else if(impl == XmlNode::IMPL_NAME)
1730 return adaptCppToXml(source,type);
1732 else if(impl == CppNode::IMPL_NAME)
1734 return adaptCppToCpp(source, type);
1736 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1738 return adaptCppToNeutral(source, type);
1743 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1744 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1745 throw ConversionException(msg.str());
1749 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1750 // const InputPort* inputPort)
1752 // bool result=true;
1756 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1761 PyObject * RuntimeSALOME::getPyOrb()
1766 PyObject * RuntimeSALOME::getBuiltins()
1771 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1776 PyObject * RuntimeSALOME::get_omnipy()
1781 omniORBpyAPI* RuntimeSALOME::getApi()
1786 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1789 return (void *)convertNeutralPyObject(type,data);
1793 return (void *)Py_None;
1797 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1802 ob=convertNeutralPyObject(type,data);
1803 std::string s=convertPyObjectToString(ob);
1805 // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1806 // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1807 // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1808 // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1809 // feel free to change this code.
1810 PyGILState_STATE gstate = PyGILState_Ensure();
1812 PyGILState_Release(gstate);
1821 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1823 return YACS::ENGINE::convertPyObjectToString(ob);
1826 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1831 PyGILState_STATE gstate = PyGILState_Ensure();
1832 mainmod = PyImport_AddModule("__main__");
1833 globals = PyModule_GetDict(mainmod);
1834 PyObject* d = PyDict_New();
1835 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1836 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1842 PyObject* new_stderr = newPyStdOut(error);
1843 PySys_SetObject((char *)"stderr", new_stderr);
1845 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1846 Py_DECREF(new_stderr);
1847 PyGILState_Release(gstate);
1848 throw Exception(error);
1850 PyGILState_Release(gstate);