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
239 void RuntimeSALOME::init(long flags, int argc, char* argv[])
241 bool ispyext = flags & RuntimeSALOME::IsPyExt;
244 PortableServer::POA_var root_poa;
245 PortableServer::POAManager_var pman;
246 CORBA::Object_var obj;
247 int nbargs = 0; char **args = 0;
248 _orb = CORBA::ORB_init (nbargs, args);
249 obj = _orb->resolve_initial_references("RootPOA");
250 root_poa = PortableServer::POA::_narrow(obj);
251 pman = root_poa->the_POAManager();
255 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
257 obj = _orb->resolve_initial_references("DynAnyFactory");
258 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
263 DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
265 // Initialize Python interpreter in embedded mode
266 if (!Py_IsInitialized())
268 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
271 Py_InitializeEx(0); // do not install signal handlers
273 PySys_SetArgv(argc, argv);
274 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
275 PyEval_SaveThread(); /* Release the thread state */
276 //here we do not have the Global Interpreter Lock
279 PyObject *mainmod,*pyapi,*res ;
281 PyGILState_STATE gstate;
282 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
284 mainmod = PyImport_AddModule("__main__");
285 globals = PyModule_GetDict(mainmod);
286 /* globals is a borrowed reference */
288 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
290 PyObject *bimod = PyImport_ImportModule("__builtin__");
291 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
292 Py_FatalError("can't add __builtins__ to __main__");
296 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
302 _omnipy = PyImport_ImportModule((char*)"_omnipy");
306 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
309 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
314 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
317 res=PyRun_String("\n"
318 "from math import *\n"
320 "sys.path.insert(0,'.')\n"
321 "from omniORB import CORBA\n"
322 "from omniORB import any\n"
323 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
324 "#print sys.getrefcount(orb)\n"
330 Py_file_input,globals,globals );
338 _pyorb = PyDict_GetItemString(globals,"orb");
339 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
342 pyany = PyDict_GetItemString(globals,"any");
343 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
346 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
350 PyGILState_Release(gstate); // Release the Global Interpreter Lock
354 // initialize the catalogLoaderFactory map with the session one
355 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
359 void RuntimeSALOME::fini()
363 PyGILState_STATE gstate = PyGILState_Ensure();
365 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
367 PyObject *mainmod, *globals;
368 mainmod = PyImport_AddModule("__main__");
369 globals = PyModule_GetDict(mainmod);
373 res=PyRun_String("orb.destroy()\n"
375 Py_file_input,globals,globals );
381 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
382 delete nodeMap["PyFunction"];
383 delete nodeMap["PyScript"];
384 delete nodeMap["SalomePythonNode"];
385 nodeMap.erase("PyFunction");
386 nodeMap.erase("PyScript");
387 nodeMap.erase("SalomePythonNode");
391 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
399 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
406 std::string RuntimeSALOME::getVersion() const
408 #ifdef YACS_DEVELOPMENT
409 return CORBA::string_dup(YACS_VERSION_STR"dev");
411 return CORBA::string_dup(YACS_VERSION_STR);
415 Proc* RuntimeSALOME::createProc(const std::string& name)
417 return new SalomeProc(name);
420 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
421 std::list<TypeCodeObjref *> ltc)
424 if(id == "") myName = "IDL:" + name + ":1.0";
426 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
429 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
430 const std::string& name,
433 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
436 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
439 if(id == "") myName = "IDL:" + name + ":1.0";
441 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
444 Bloc* RuntimeSALOME::createBloc(const std::string& name)
446 return new Bloc(name);
449 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
451 return new WhileLoop(name);
454 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
456 return new ForLoop(name);
459 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
460 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
462 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
463 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
464 ol->edGetNbOfBranchesPort()->edInit(1);
468 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
473 node = new PresetNode(name);
476 else if(kind == "study" )
478 return new StudyInNode(name);
480 std::string msg="DataNode kind ("+kind+") unknown";
481 throw Exception(msg);
484 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
488 return new OutNode(name);
490 else if(kind == "study" )
492 return new StudyOutNode(name);
495 std::string msg="OutDataNode kind ("+kind+") unknown";
496 throw Exception(msg);
499 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
501 InlineFuncNode* node;
502 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
504 node = new PyFuncNode(name);
507 if(kind == DistributedPythonNode::KIND)
508 return new DistributedPythonNode(name);
509 std::string msg="FuncNode kind ("+kind+") unknown";
510 throw Exception(msg);
513 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
516 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
518 node = new PythonNode(name);
521 std::string msg="ScriptNode kind ("+kind+") unknown";
522 throw Exception(msg);
525 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
528 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
530 node = new CORBANode(name);
533 else if(kind == XmlNode::KIND)
535 node = new XmlNode(name);
538 std::string msg="RefNode kind ("+kind+") unknown";
539 throw Exception(msg);
542 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
545 if(kind == "" || kind == SalomeNode::KIND )
547 node=new SalomeNode(name);
550 else if (kind == CppNode::KIND)
552 node = new CppNode(name);
555 std::string msg="CompoNode kind ("+kind+") unknown";
556 throw Exception(msg);
559 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
561 if(kind == "" || kind == SalomeNode::KIND )
562 return new SalomePythonNode(name);
563 std::string msg="CompoNode kind ("+kind+") unknown";
564 throw Exception(msg);
567 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
568 const std::string& kind)
570 ComponentInstance* compo;
571 if(kind == "" || kind == SalomeComponent::KIND)
572 return new SalomeComponent(name);
573 else if(kind == CORBAComponent::KIND)
574 return new CORBAComponent(name);
575 else if(kind == SalomePythonComponent::KIND)
576 return new SalomePythonComponent(name);
577 else if (kind == CppComponent::KIND)
578 return new CppComponent(name);
579 std::string msg="Component Instance kind ("+kind+") unknown";
580 throw Exception(msg);
583 Container *RuntimeSALOME::createContainer(const std::string& kind)
585 if(kind == "" || kind == SalomeComponent::KIND)
586 return new SalomeContainer;
587 else if (kind == CppComponent::KIND)
588 return new CppContainer;
589 std::string msg="Container kind ("+kind+") unknown";
590 throw Exception(msg);
593 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
594 const std::string& impl,
598 if(impl == CppNode::IMPL_NAME)
600 return new InputCppPort(name, node, type);
602 else if(impl == PythonNode::IMPL_NAME)
604 return new InputPyPort(name, node, type);
606 else if(impl == CORBANode::IMPL_NAME)
608 return new InputCorbaPort(name, node, type);
610 else if(impl == XmlNode::IMPL_NAME)
612 return new InputXmlPort(name, node, type);
617 msg << "Cannot create " << impl << " InputPort" ;
618 msg << " ("__FILE__ << ":" << __LINE__ << ")";
619 throw Exception(msg.str());
623 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
624 const std::string& impl,
628 if(impl == CppNode::IMPL_NAME)
630 return new OutputCppPort(name, node, type);
632 else if(impl == PythonNode::IMPL_NAME)
634 return new OutputPyPort(name, node, type);
636 else if(impl == CORBANode::IMPL_NAME)
638 return new OutputCorbaPort(name, node, type);
640 else if(impl == XmlNode::IMPL_NAME)
642 return new OutputXmlPort(name, node, type);
647 msg << "Cannot create " << impl << " OutputPort" ;
648 msg << " ("__FILE__ << ":" << __LINE__ << ")";
649 throw Exception(msg.str());
653 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
654 Node *node,TypeCode *type)
656 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
657 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
659 return new InputCalStreamPort(name,node,type);
663 return new InputDataStreamPort(name,node,type);
667 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
668 Node *node,TypeCode *type)
670 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
671 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
673 return new OutputCalStreamPort(name,node,type);
677 return new OutputDataStreamPort(name,node,type);
681 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
683 * \param source : InputPort to be adapted
684 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
685 * \param type : data type provided by the InputPort
686 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
688 * \return : adapted InputPort
690 InputPort* RuntimeSALOME::adapt(InputPort* source,
691 const std::string& impl,
692 TypeCode * type,bool init) throw (ConversionException)
694 string imp_source=source->getNode()->getImplementation();
695 if(imp_source == PythonNode::IMPL_NAME)
697 return adapt((InputPyPort*)source,impl,type,init);
699 else if(imp_source == CppNode::IMPL_NAME)
701 return adapt((InputCppPort*)source,impl,type,init);
703 else if(imp_source == CORBANode::IMPL_NAME)
705 return adapt((InputCorbaPort*)source,impl,type,init);
707 else if(imp_source == XmlNode::IMPL_NAME)
709 return adapt((InputXmlPort*)source,impl,type,init);
711 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
713 return adaptNeutral(source,impl,type,init);
718 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
719 msg << " ("__FILE__ << ":" << __LINE__ << ")";
720 throw ConversionException(msg.str());
724 //! Adapter function for InPropertyPort
726 * \param source : InPropertyPort to be adapted
727 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
728 * \param type : data type provided by the InPropertyPort
729 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
731 * \return : adapted InputPort
733 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
734 const std::string& impl,
735 TypeCode * type,bool init) throw (ConversionException)
737 return adaptNeutral((InputPort *)source,impl,type,init);
740 //! Adapt a Neutral input port to a Corba output port
742 * \param inport : Neutral input port to adapt to Corba type type
743 * \param type : output port type
744 * \return an adaptated input port of type InputCorbaPort
746 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
747 TypeCode * type) throw (ConversionException)
749 // BEWARE : using the generic check
750 if(inport->edGetType()->isAdaptable(type))
752 //the output data is convertible to inport type
753 return new CorbaNeutral(inport);
755 //non convertible type
757 msg << "Cannot connect Corba output port with type: " << type->id() ;
758 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
760 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
762 throw ConversionException(msg.str());
765 //! Adapt a Neutral input port to a Python output port
767 * \param inport : input port to adapt to Python type type
768 * \param type : output port type
769 * \return an adaptated input port of type InputPyPort
771 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
772 TypeCode * type) throw (ConversionException)
774 // BEWARE : using the generic check
775 if(inport->edGetType()->isAdaptable(type))
778 return new PyNeutral(inport);
780 //non convertible type
782 msg << "Cannot connect Python output port with type: " << type->id() ;
783 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
785 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
787 throw ConversionException(msg.str());
790 //! Adapt a Neutral input port to a Xml output port
792 * \param inport : input port to adapt to Xml type type
793 * \param type : output port type
794 * \return an input port of type InputXmlPort
796 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
797 TypeCode * type) throw (ConversionException)
799 // BEWARE : using the generic check
800 if(inport->edGetType()->isAdaptable(type))
803 return new XmlNeutral(inport);
805 //non convertible type
807 msg << "Cannot connect Xml output port with type: " << type->id() ;
808 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
810 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
812 throw ConversionException(msg.str());
815 //! Adapt a Neutral input port to a C++ output port
817 * \param inport : input port to adapt to C++ type type
818 * \param type : output port type
819 * \return an input port of type InputCppPort
821 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
822 TypeCode * type) throw (ConversionException)
824 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
825 if(isAdaptableNeutralCpp(type,inport->edGetType()))
828 return new CppNeutral(inport);
830 //non convertible type
832 msg << "Cannot connect Cpp output port with type: " << type->id() ;
833 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
835 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
837 throw ConversionException(msg.str());
840 //! Adapt a Neutral input port to connect it to an output port with a given implementation
842 * \param source : Neutral input port to adapt to implementation impl and type type
843 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
844 * \param type : output port supported type
845 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
846 * \return the adaptated port
848 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
849 const std::string& impl,
850 TypeCode * type,bool init) throw (ConversionException)
852 if(impl == CppNode::IMPL_NAME)
854 return adaptNeutralToCpp(source,type);
856 else if(impl == PythonNode::IMPL_NAME)
858 return adaptNeutralToPython(source,type);
860 else if(impl == CORBANode::IMPL_NAME)
862 return adaptNeutralToCorba(source,type);
864 else if(impl == XmlNode::IMPL_NAME )
866 return adaptNeutralToXml(source,type);
868 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
871 return new NeutralInit(source);
873 return new ProxyPort(source);
876 msg << "Cannot connect InputPort : unknown implementation " << impl;
877 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
878 throw ConversionException(msg.str());
881 //! Adapt a XML input port to connect it to a CORBA output port
883 * \param inport : input port to adapt to CORBA type type
884 * \param type : type supported by output port
885 * \return an adaptator port of type InputCorbaPort
888 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
889 TypeCode * type) throw (ConversionException)
891 if(isAdaptableXmlCorba(type,inport->edGetType()))
893 //output type is convertible to input type
894 return new CorbaXml(inport);
896 //output type is not convertible
898 msg << "Cannot connect Corba output port with type: " << type->id() ;
899 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
901 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
903 throw ConversionException(msg.str());
906 //! Adapt a XML input port to a Python output port
908 * \param inport : input port to adapt to Python type type
909 * \param type : output port type
910 * \return an adaptated input port of type InputPyPort
912 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
913 TypeCode * type) throw (ConversionException)
915 if(inport->edGetType()->isAdaptable(type))
917 //the output data is convertible to inport type
918 return new PyXml(inport);
920 //non convertible type
922 msg << "Cannot connect Python output port with type: " << type->id() ;
923 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
925 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
927 throw ConversionException(msg.str());
930 //! Adapt a XML input port to a C++ output port
932 * \param inport : input port to adapt to C++ type type
933 * \param type : output port type
934 * \return an adaptated input port of type InputPyPort
936 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
937 TypeCode * type) throw (ConversionException)
939 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
940 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
941 if(type->isAdaptable(inport->edGetType()))
943 //the output data is convertible to inport type
944 return new CppXml(inport);
946 //non convertible type
948 msg << "Cannot connect Cpp output port with type: " << type->id() ;
949 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
951 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
953 throw ConversionException(msg.str());
956 //! Adapt a XML input port to a Neutral output port
958 * \param inport : input port to adapt to Neutral type type
959 * \param type : output port type
960 * \return an adaptated input port of type Neutralxxxx
962 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
963 TypeCode * type) throw (ConversionException)
965 if(inport->edGetType()->isAdaptable(type))
967 //the output data is convertible to inport type
968 return new NeutralXml(inport);
970 //non convertible type
972 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
973 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
974 throw ConversionException(msg.str());
977 //! Adapt a XML input port to a Xml output port
979 * \param inport : input port to adapt to Xml type type
980 * \param type : output port type
981 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
982 * \return an adaptated input port of type Xmlxxxx
984 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
985 TypeCode * type,bool init) throw (ConversionException)
988 return new ProxyPort(inport);
990 if(inport->edGetType()->isAdaptable(type))
991 return new ProxyPort(inport);
994 msg << "Cannot connect Xml output port with type: " << type->id() ;
995 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
997 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
999 throw ConversionException(msg.str());
1002 //! Adapt an Xml input port to an output port which implementation is given by impl
1004 * \param source : input port to adapt to implementation impl and type type
1005 * \param impl : output port implementation (C++, Python or Corba)
1006 * \param type : output port supported type
1007 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1008 * \return the adaptated port
1011 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1012 const std::string& impl,
1013 TypeCode * type,bool init) throw (ConversionException)
1015 if(impl == CORBANode::IMPL_NAME)
1017 return adaptXmlToCorba(source,type);
1019 else if(impl == PythonNode::IMPL_NAME)
1021 return adaptXmlToPython(source,type);
1023 else if(impl == CppNode::IMPL_NAME)
1025 return adaptXmlToCpp(source,type);
1027 else if(impl == XmlNode::IMPL_NAME )
1029 return adaptXmlToXml(source,type,init);
1031 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1033 return adaptXmlToNeutral(source,type);
1038 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1039 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1040 throw ConversionException(msg.str());
1045 //! Adapt a CORBA input port to a CORBA output port
1047 * \param inport : input port to adapt to CORBA outport data type
1048 * \param type : outport data type
1049 * \return an adaptator port of type InputCORBAPort
1051 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1052 TypeCode * type) throw (ConversionException)
1054 if(type->isA(inport->edGetType()))
1056 //types are compatible : no conversion
1057 //outport data type is more specific than inport required type
1058 //so the inport can be used safely
1059 return new ProxyPort(inport);
1061 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1063 //ouport data can be converted to inport data type
1064 return new CorbaCorba(inport);
1066 //outport data can not be converted
1068 msg << "Cannot connect Corba output port with type: " << type->id() ;
1069 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1071 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1073 throw ConversionException(msg.str());
1076 //! Adapt a CORBA input port to a Python output port
1078 * \param inport : input port to adapt to Python type type
1079 * \param type : outport data type
1080 * \return an adaptator port of type InputPyPort
1083 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1084 TypeCode * type) throw (ConversionException)
1086 if(inport->edGetType()->kind() == Double)
1088 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1090 else if(inport->edGetType()->kind() == Int)
1092 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1094 else if(inport->edGetType()->kind() == String)
1096 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1098 else if(inport->edGetType()->kind() == Bool)
1100 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1102 else if(inport->edGetType()->kind() == Objref )
1104 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1106 return new PyCorbaObjref(inport);
1111 msg << "Cannot connect Python output port with type: " << type->id() ;
1112 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1113 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1114 throw ConversionException(msg.str());
1117 else if(inport->edGetType()->kind() == Sequence)
1119 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1121 return new PyCorbaSequence(inport);
1126 msg << "Cannot convert this sequence type " ;
1127 msg << __FILE__ << ":" <<__LINE__;
1128 throw ConversionException(msg.str());
1131 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1133 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1135 return new PyCorbaStruct(inport);
1140 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1141 msg << __FILE__ << ":" <<__LINE__;
1142 throw ConversionException(msg.str());
1145 // Adaptation not possible
1147 msg << "Cannot connect Python output port with type: " << type->id() ;
1148 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1150 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1152 throw ConversionException(msg.str());
1155 //! Adapt a CORBA input port to connect it to a XML output port
1157 * \param inport : input port to adapt to Xml type type
1158 * \param type : type supported by output port
1159 * \return an adaptator port of type InputXmlPort
1162 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1163 TypeCode * type) throw (ConversionException)
1165 // BEWARE : using the generic check
1166 if(inport->edGetType()->isAdaptable(type))
1168 //output type is convertible to input type
1169 return new XmlCorba(inport);
1171 //output type is not convertible
1173 msg << "Cannot connect Xml output port with type: " << type->id() ;
1174 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1176 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1178 throw ConversionException(msg.str());
1181 //! Adapt a CORBA input port to a C++ output port
1183 * \param inport : input port to adapt to C++ type type
1184 * \param type : outport data type
1185 * \return an adaptator port of type InputCPPPort
1188 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1189 TypeCode * type) throw (ConversionException)
1191 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1192 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1194 //output type is convertible to input type
1195 return new CppCorba(inport);
1197 //output type is not convertible
1199 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1200 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1202 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1204 throw ConversionException(msg.str());
1207 //! Adapt a CORBA input port to a neutral data
1209 * \param inport : InputPort to adapt to Neutral type type
1210 * \param type : outport data type
1211 * \return an adaptator port of type Neutralxxxx
1214 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1215 TypeCode * type) throw (ConversionException)
1217 if(inport->edGetType()->kind() == Double)
1219 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1221 else if(inport->edGetType()->kind() == Int)
1223 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1225 else if(inport->edGetType()->kind() == String)
1227 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1229 else if(inport->edGetType()->kind() == Bool)
1231 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1233 else if(inport->edGetType()->kind() == Objref)
1235 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1237 else if(inport->edGetType()->kind() == Sequence)
1239 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1240 return new NeutralCorbaSequence(inport);
1244 msg << "Cannot convert this sequence type " ;
1245 msg << __FILE__ << ":" <<__LINE__;
1246 throw ConversionException(msg.str());
1249 else if(inport->edGetType()->kind() == Struct)
1251 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1254 // Adaptation not possible
1256 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1257 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1259 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1261 throw ConversionException(msg.str());
1264 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1266 * \param source : input port to adapt to implementation impl and type type
1267 * \param impl : output port implementation (C++, Python or Corba)
1268 * \param type : outport data type
1269 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1270 * \return an adaptator port which type depends on impl
1273 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1274 const std::string& impl,
1275 TypeCode * type,bool init) throw (ConversionException)
1277 if(impl == CppNode::IMPL_NAME)
1279 return adaptCorbaToCpp(source,type);
1281 else if(impl == PythonNode::IMPL_NAME)
1283 return adaptCorbaToPython(source,type);
1285 else if(impl == CORBANode::IMPL_NAME)
1288 return adaptCorbaToCorba(source,type);
1290 return adaptCorbaToCorba(source,type);
1292 else if(impl == XmlNode::IMPL_NAME )
1294 return adaptCorbaToXml(source,type);
1296 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1298 return adaptCorbaToNeutral(source,type);
1303 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1304 msg << __FILE__ << ":" <<__LINE__;
1305 throw ConversionException(msg.str());
1309 //! Adapt a Python input port to a Python output port
1311 * No need to make conversion or cast.
1312 * Only check, it's possible.
1313 * \param inport : InputPort to adapt to Python type type
1314 * \param type : outport data type
1315 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1316 * \return an adaptator port of type InputPyPort
1319 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1320 TypeCode * type,bool init) throw (ConversionException)
1323 return new PyInit(inport);
1325 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1327 //output data is convertible to input type
1328 //With python, no need to convert. Conversion will be done automatically
1329 //by the interpreter
1330 return new ProxyPort(inport);
1332 //output data is not convertible to input type
1334 msg << "Cannot connect Python output port with type: " << type->id() ;
1335 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1337 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1339 throw ConversionException(msg.str());
1342 //! Adapt a Python input port to a C++ output port
1344 * \param inport : InputPort to adapt to C++ type type
1345 * \param type : outport data type
1346 * \return an adaptator port of C++ type (InputCppPort)
1349 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1350 TypeCode * type) throw (ConversionException)
1352 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1353 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1355 //output type is convertible to input type
1356 return new CppPy(inport);
1358 //output type is not convertible
1360 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1361 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1363 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1365 throw ConversionException(msg.str());
1368 //! Adapt a Python input port to a Neutral data port
1370 * \param inport : InputPort to adapt to Neutral type type
1371 * \param type : outport data type
1372 * \return an adaptator port of Neutral type (Neutralxxxx)
1375 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1376 TypeCode * type) throw (ConversionException)
1378 if(inport->edGetType()->kind() == Double)
1380 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1382 else if(inport->edGetType()->kind() == Int)
1384 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1386 else if(inport->edGetType()->kind() == String)
1388 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1390 else if(inport->edGetType()->kind() == Bool)
1392 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1394 else if(inport->edGetType()->kind() == Objref)
1396 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1398 else if(inport->edGetType()->kind() == Sequence)
1400 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1401 return new NeutralPySequence(inport);
1405 msg << "Cannot convert this sequence type " ;
1406 msg << __FILE__ << ":" <<__LINE__;
1407 throw ConversionException(msg.str());
1410 else if(inport->edGetType()->kind() == Struct)
1412 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1415 // Adaptation not possible
1417 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1418 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1420 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1422 throw ConversionException(msg.str());
1425 //! Adapt a Python input port to a Corba output port
1427 * Always convert the data
1428 * \param inport : InputPort to adapt to Corba type type
1429 * \param type : outport data type
1430 * \return an adaptator port of Corba type (InputCorbaPort)
1433 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1434 TypeCode * type) throw (ConversionException)
1436 if(inport->edGetType()->kind() == Double)
1438 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1440 else if(inport->edGetType()->kind() == Int)
1442 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1444 else if(inport->edGetType()->kind() == String)
1446 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1448 else if(inport->edGetType()->kind() == Bool)
1450 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1452 else if(inport->edGetType()->kind() == Objref)
1454 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1456 return new CorbaPyObjref(inport);
1461 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1462 msg << " " << __FILE__ << ":" <<__LINE__;
1463 throw ConversionException(msg.str());
1466 else if(inport->edGetType()->kind() == Sequence)
1468 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1470 return new CorbaPySequence(inport);
1475 msg << "Cannot convert this sequence type " ;
1476 msg << __FILE__ << ":" <<__LINE__;
1477 throw ConversionException(msg.str());
1480 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1482 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1484 return new CorbaPyStruct(inport);
1489 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1490 msg << " " << __FILE__ << ":" <<__LINE__;
1491 throw ConversionException(msg.str());
1494 // Adaptation not possible
1496 msg << "Cannot connect Corba output port with type: " << type->id() ;
1497 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1499 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1501 throw ConversionException(msg.str());
1504 //! Adapt a Python input port to a Xml output port
1506 * \param inport : input port to adapt to Xml type type
1507 * \param type : output port type
1508 * \return an input port of type InputXmlPort
1511 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1512 TypeCode * type) throw (ConversionException)
1514 // BEWARE : using the generic check
1515 if(inport->edGetType()->isAdaptable(type))
1518 return new XmlPython(inport);
1520 //non convertible type
1522 msg << "Cannot connect Xml output port with type: " << type->id() ;
1523 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1525 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1527 throw ConversionException(msg.str());
1530 //! Adapt a Python input port to an output port with a given implementation
1532 * \param source : input port to adapt to implementation impl and type type
1533 * \param impl : output port implementation (C++, Python or Corba)
1534 * \param type : output port type
1535 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1536 * \return adaptated input port
1539 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1540 const std::string& impl,
1541 TypeCode * type,bool init) throw (ConversionException)
1543 if(impl == CppNode::IMPL_NAME)
1545 return adaptPythonToCpp(source,type);
1547 else if(impl == PythonNode::IMPL_NAME)
1549 return adaptPythonToPython(source,type,init);
1551 else if(impl == CORBANode::IMPL_NAME)
1553 return adaptPythonToCorba(source,type);
1555 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1557 return adaptPythonToNeutral(source,type);
1559 else if(impl == XmlNode::IMPL_NAME)
1561 return adaptPythonToXml(source,type);
1566 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1567 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1568 throw ConversionException(msg.str());
1573 //! Adapt a C++ input port to connect it to a CORBA output port
1575 * \param inport : input port to adapt to CORBA type type
1576 * \param type : type supported by output port
1577 * \return an adaptator port of type InputCorbaPort
1580 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1581 TypeCode * type) throw (ConversionException)
1583 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1584 if(isAdaptableCppCorba(type,inport->edGetType()))
1586 //output type is convertible to input type
1587 return new CorbaCpp(inport);
1589 //output type is not convertible
1591 msg << "Cannot connect Corba output port with type: " << type->id() ;
1592 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1594 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1596 throw ConversionException(msg.str());
1599 //! Adapt a C++ input port to a Python output port
1601 * \param inport : input port to adapt to Python type type
1602 * \param type : output port type
1603 * \return an adaptated input port of type InputPyPort
1605 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1606 TypeCode * type) throw (ConversionException)
1608 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1609 if(isAdaptableCppPyObject(type,inport->edGetType()))
1611 //output type is convertible to input type
1612 return new PyCpp(inport);
1614 //output type is not convertible
1616 msg << "Cannot connect Python output port with type: " << type->id() ;
1617 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1619 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1621 throw ConversionException(msg.str());
1624 //! Adapt a C++ input port to a C++ output port
1626 * \param inport : input port to adapt to C++ type type
1627 * \param type : output port type
1628 * \return an adaptated input port of type InputPyPort
1630 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1631 TypeCode * type) throw (ConversionException)
1633 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1634 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1635 if(type->isAdaptable(inport->edGetType()))
1637 //the output data is convertible to inport type
1638 return new CppCpp(inport);
1640 //non convertible type
1642 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1643 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1645 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1647 throw ConversionException(msg.str());
1650 //! Adapt a C++ input port to a Neutral output port
1652 * \param inport : input port to adapt to C++ type type
1653 * \param type : output port type
1654 * \return an adaptated input port of type InputPyPort
1656 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1657 TypeCode * type) throw (ConversionException)
1659 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1660 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1661 if(type->isAdaptable(inport->edGetType()))
1663 //the output data is convertible to inport type
1664 return new NeutralCpp(inport);
1666 //non convertible type
1668 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1669 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1671 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1673 throw ConversionException(msg.str());
1676 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1677 TypeCode * type) throw (ConversionException)
1679 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1680 if(isAdaptableCppXml(type,inport->edGetType()))
1683 return new XmlCpp(inport);
1685 //non convertible type
1687 msg << "Cannot connect Xml output port with type: " << type->id() ;
1688 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1690 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1692 throw ConversionException(msg.str());
1695 //! Adapt a C++ input port to connect it to an output port with a given implementation
1697 * \param source : input port to adapt to implementation impl and type type
1698 * \param impl : output port implementation (C++, Python or Corba)
1699 * \param type : output port supported type
1700 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1701 * \return the adaptated port
1704 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1705 const std::string& impl,
1706 TypeCode * type,bool init) throw (ConversionException)
1708 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1709 if(impl == CORBANode::IMPL_NAME)
1711 return adaptCppToCorba(source,type);
1713 else if(impl == PythonNode::IMPL_NAME)
1715 return adaptCppToPython(source,type);
1717 else if(impl == XmlNode::IMPL_NAME)
1719 return adaptCppToXml(source,type);
1721 else if(impl == CppNode::IMPL_NAME)
1723 return adaptCppToCpp(source, type);
1725 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1727 return adaptCppToNeutral(source, type);
1732 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1733 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1734 throw ConversionException(msg.str());
1738 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1739 // const InputPort* inputPort)
1741 // bool result=true;
1745 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1750 PyObject * RuntimeSALOME::getPyOrb()
1755 PyObject * RuntimeSALOME::getBuiltins()
1760 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1765 PyObject * RuntimeSALOME::get_omnipy()
1770 omniORBpyAPI* RuntimeSALOME::getApi()
1775 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1778 return (void *)convertNeutralPyObject(type,data);
1782 return (void *)Py_None;
1786 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1791 ob=convertNeutralPyObject(type,data);
1792 std::string s=convertPyObjectToString(ob);
1794 // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1795 // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1796 // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1797 // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1798 // feel free to change this code.
1799 PyGILState_STATE gstate = PyGILState_Ensure();
1801 PyGILState_Release(gstate);
1810 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1812 return YACS::ENGINE::convertPyObjectToString(ob);
1815 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1820 PyGILState_STATE gstate = PyGILState_Ensure();
1821 mainmod = PyImport_AddModule("__main__");
1822 globals = PyModule_GetDict(mainmod);
1823 PyObject* d = PyDict_New();
1824 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1825 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1831 PyObject* new_stderr = newPyStdOut(error);
1832 PySys_SetObject((char *)"stderr", new_stderr);
1834 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1835 Py_DECREF(new_stderr);
1836 PyGILState_Release(gstate);
1837 throw Exception(error);
1839 PyGILState_Release(gstate);