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) // singleton creation (not thread safe!)
127 if (! Runtime::_singleton)
129 RuntimeSALOME* r=new RuntimeSALOME(flags);
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)
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);
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)
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 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
274 PyEval_SaveThread(); /* Release the thread state */
275 //here we do not have the Global Interpreter Lock
278 PyObject *mainmod,*pyapi,*res ;
280 PyGILState_STATE gstate;
281 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
283 mainmod = PyImport_AddModule("__main__");
284 globals = PyModule_GetDict(mainmod);
285 /* globals is a borrowed reference */
287 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
289 PyObject *bimod = PyImport_ImportModule("__builtin__");
290 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
291 Py_FatalError("can't add __builtins__ to __main__");
295 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
301 _omnipy = PyImport_ImportModule((char*)"_omnipy");
305 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
308 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
313 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
316 res=PyRun_String("\n"
317 "from math import *\n"
319 "sys.path.insert(0,'.')\n"
320 "from omniORB import CORBA\n"
321 "from omniORB import any\n"
322 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
323 "#print sys.getrefcount(orb)\n"
329 Py_file_input,globals,globals );
337 _pyorb = PyDict_GetItemString(globals,"orb");
338 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
341 pyany = PyDict_GetItemString(globals,"any");
342 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
345 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
349 PyGILState_Release(gstate); // Release the Global Interpreter Lock
353 // initialize the catalogLoaderFactory map with the session one
354 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
358 void RuntimeSALOME::fini()
362 PyGILState_STATE gstate = PyGILState_Ensure();
364 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
366 PyObject *mainmod, *globals;
367 mainmod = PyImport_AddModule("__main__");
368 globals = PyModule_GetDict(mainmod);
372 res=PyRun_String("orb.destroy()\n"
374 Py_file_input,globals,globals );
380 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
381 delete nodeMap["PyFunction"];
382 delete nodeMap["PyScript"];
383 delete nodeMap["SalomePythonNode"];
384 nodeMap.erase("PyFunction");
385 nodeMap.erase("PyScript");
386 nodeMap.erase("SalomePythonNode");
390 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
398 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
405 std::string RuntimeSALOME::getVersion() const
407 #ifdef YACS_DEVELOPMENT
408 return CORBA::string_dup(YACS_VERSION_STR"dev");
410 return CORBA::string_dup(YACS_VERSION_STR);
414 Proc* RuntimeSALOME::createProc(const std::string& name)
416 return new SalomeProc(name);
419 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
420 std::list<TypeCodeObjref *> ltc)
423 if(id == "") myName = "IDL:" + name + ":1.0";
425 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
428 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
429 const std::string& name,
432 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
435 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
438 if(id == "") myName = "IDL:" + name + ":1.0";
440 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
443 Bloc* RuntimeSALOME::createBloc(const std::string& name)
445 return new Bloc(name);
448 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
450 return new WhileLoop(name);
453 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
455 return new ForLoop(name);
458 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
459 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
461 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
462 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
463 ol->edGetNbOfBranchesPort()->edInit(1);
467 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
472 node = new PresetNode(name);
475 else if(kind == "study" )
477 return new StudyInNode(name);
479 std::string msg="DataNode kind ("+kind+") unknown";
480 throw Exception(msg);
483 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
487 return new OutNode(name);
489 else if(kind == "study" )
491 return new StudyOutNode(name);
494 std::string msg="OutDataNode kind ("+kind+") unknown";
495 throw Exception(msg);
498 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
500 InlineFuncNode* node;
501 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
503 node = new PyFuncNode(name);
506 if(kind == DistributedPythonNode::KIND)
507 return new DistributedPythonNode(name);
508 std::string msg="FuncNode kind ("+kind+") unknown";
509 throw Exception(msg);
512 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
515 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
517 node = new PythonNode(name);
520 std::string msg="ScriptNode kind ("+kind+") unknown";
521 throw Exception(msg);
524 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
527 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
529 node = new CORBANode(name);
532 else if(kind == XmlNode::KIND)
534 node = new XmlNode(name);
537 std::string msg="RefNode kind ("+kind+") unknown";
538 throw Exception(msg);
541 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
544 if(kind == "" || kind == SalomeNode::KIND )
546 node=new SalomeNode(name);
549 else if (kind == CppNode::KIND)
551 node = new CppNode(name);
554 std::string msg="CompoNode kind ("+kind+") unknown";
555 throw Exception(msg);
558 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
560 if(kind == "" || kind == SalomeNode::KIND )
561 return new SalomePythonNode(name);
562 std::string msg="CompoNode kind ("+kind+") unknown";
563 throw Exception(msg);
566 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
567 const std::string& kind)
569 ComponentInstance* compo;
570 if(kind == "" || kind == SalomeComponent::KIND)
571 return new SalomeComponent(name);
572 else if(kind == CORBAComponent::KIND)
573 return new CORBAComponent(name);
574 else if(kind == SalomePythonComponent::KIND)
575 return new SalomePythonComponent(name);
576 else if (kind == CppComponent::KIND)
577 return new CppComponent(name);
578 std::string msg="Component Instance kind ("+kind+") unknown";
579 throw Exception(msg);
582 Container *RuntimeSALOME::createContainer(const std::string& kind)
584 if(kind == "" || kind == SalomeComponent::KIND)
585 return new SalomeContainer;
586 else if (kind == CppComponent::KIND)
587 return new CppContainer;
588 std::string msg="Container kind ("+kind+") unknown";
589 throw Exception(msg);
592 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
593 const std::string& impl,
597 if(impl == CppNode::IMPL_NAME)
599 return new InputCppPort(name, node, type);
601 else if(impl == PythonNode::IMPL_NAME)
603 return new InputPyPort(name, node, type);
605 else if(impl == CORBANode::IMPL_NAME)
607 return new InputCorbaPort(name, node, type);
609 else if(impl == XmlNode::IMPL_NAME)
611 return new InputXmlPort(name, node, type);
616 msg << "Cannot create " << impl << " InputPort" ;
617 msg << " ("__FILE__ << ":" << __LINE__ << ")";
618 throw Exception(msg.str());
622 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
623 const std::string& impl,
627 if(impl == CppNode::IMPL_NAME)
629 return new OutputCppPort(name, node, type);
631 else if(impl == PythonNode::IMPL_NAME)
633 return new OutputPyPort(name, node, type);
635 else if(impl == CORBANode::IMPL_NAME)
637 return new OutputCorbaPort(name, node, type);
639 else if(impl == XmlNode::IMPL_NAME)
641 return new OutputXmlPort(name, node, type);
646 msg << "Cannot create " << impl << " OutputPort" ;
647 msg << " ("__FILE__ << ":" << __LINE__ << ")";
648 throw Exception(msg.str());
652 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
653 Node *node,TypeCode *type)
655 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
656 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
658 return new InputCalStreamPort(name,node,type);
662 return new InputDataStreamPort(name,node,type);
666 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
667 Node *node,TypeCode *type)
669 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
670 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
672 return new OutputCalStreamPort(name,node,type);
676 return new OutputDataStreamPort(name,node,type);
680 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
682 * \param source : InputPort to be adapted
683 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
684 * \param type : data type provided by the InputPort
685 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
687 * \return : adapted InputPort
689 InputPort* RuntimeSALOME::adapt(InputPort* source,
690 const std::string& impl,
691 TypeCode * type,bool init) throw (ConversionException)
693 string imp_source=source->getNode()->getImplementation();
694 if(imp_source == PythonNode::IMPL_NAME)
696 return adapt((InputPyPort*)source,impl,type,init);
698 else if(imp_source == CppNode::IMPL_NAME)
700 return adapt((InputCppPort*)source,impl,type,init);
702 else if(imp_source == CORBANode::IMPL_NAME)
704 return adapt((InputCorbaPort*)source,impl,type,init);
706 else if(imp_source == XmlNode::IMPL_NAME)
708 return adapt((InputXmlPort*)source,impl,type,init);
710 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
712 return adaptNeutral(source,impl,type,init);
717 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
718 msg << " ("__FILE__ << ":" << __LINE__ << ")";
719 throw ConversionException(msg.str());
723 //! Adapter function for InPropertyPort
725 * \param source : InPropertyPort to be adapted
726 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
727 * \param type : data type provided by the InPropertyPort
728 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
730 * \return : adapted InputPort
732 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
733 const std::string& impl,
734 TypeCode * type,bool init) throw (ConversionException)
736 return adaptNeutral((InputPort *)source,impl,type,init);
739 //! Adapt a Neutral input port to a Corba output port
741 * \param inport : Neutral input port to adapt to Corba type type
742 * \param type : output port type
743 * \return an adaptated input port of type InputCorbaPort
745 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
746 TypeCode * type) throw (ConversionException)
748 // BEWARE : using the generic check
749 if(inport->edGetType()->isAdaptable(type))
751 //the output data is convertible to inport type
752 return new CorbaNeutral(inport);
754 //non convertible type
756 msg << "Cannot connect Corba output port with type: " << type->id() ;
757 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
759 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
761 throw ConversionException(msg.str());
764 //! Adapt a Neutral input port to a Python output port
766 * \param inport : input port to adapt to Python type type
767 * \param type : output port type
768 * \return an adaptated input port of type InputPyPort
770 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
771 TypeCode * type) throw (ConversionException)
773 // BEWARE : using the generic check
774 if(inport->edGetType()->isAdaptable(type))
777 return new PyNeutral(inport);
779 //non convertible type
781 msg << "Cannot connect Python output port with type: " << type->id() ;
782 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
784 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
786 throw ConversionException(msg.str());
789 //! Adapt a Neutral input port to a Xml output port
791 * \param inport : input port to adapt to Xml type type
792 * \param type : output port type
793 * \return an input port of type InputXmlPort
795 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
796 TypeCode * type) throw (ConversionException)
798 // BEWARE : using the generic check
799 if(inport->edGetType()->isAdaptable(type))
802 return new XmlNeutral(inport);
804 //non convertible type
806 msg << "Cannot connect Xml output port with type: " << type->id() ;
807 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
809 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
811 throw ConversionException(msg.str());
814 //! Adapt a Neutral input port to a C++ output port
816 * \param inport : input port to adapt to C++ type type
817 * \param type : output port type
818 * \return an input port of type InputCppPort
820 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
821 TypeCode * type) throw (ConversionException)
823 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
824 if(isAdaptableNeutralCpp(type,inport->edGetType()))
827 return new CppNeutral(inport);
829 //non convertible type
831 msg << "Cannot connect Cpp output port with type: " << type->id() ;
832 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
834 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
836 throw ConversionException(msg.str());
839 //! Adapt a Neutral input port to connect it to an output port with a given implementation
841 * \param source : Neutral input port to adapt to implementation impl and type type
842 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
843 * \param type : output port supported type
844 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
845 * \return the adaptated port
847 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
848 const std::string& impl,
849 TypeCode * type,bool init) throw (ConversionException)
851 if(impl == CppNode::IMPL_NAME)
853 return adaptNeutralToCpp(source,type);
855 else if(impl == PythonNode::IMPL_NAME)
857 return adaptNeutralToPython(source,type);
859 else if(impl == CORBANode::IMPL_NAME)
861 return adaptNeutralToCorba(source,type);
863 else if(impl == XmlNode::IMPL_NAME )
865 return adaptNeutralToXml(source,type);
867 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
870 return new NeutralInit(source);
872 return new ProxyPort(source);
875 msg << "Cannot connect InputPort : unknown implementation " << impl;
876 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
877 throw ConversionException(msg.str());
880 //! Adapt a XML input port to connect it to a CORBA output port
882 * \param inport : input port to adapt to CORBA type type
883 * \param type : type supported by output port
884 * \return an adaptator port of type InputCorbaPort
887 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
888 TypeCode * type) throw (ConversionException)
890 if(isAdaptableXmlCorba(type,inport->edGetType()))
892 //output type is convertible to input type
893 return new CorbaXml(inport);
895 //output type is not convertible
897 msg << "Cannot connect Corba output port with type: " << type->id() ;
898 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
900 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
902 throw ConversionException(msg.str());
905 //! Adapt a XML input port to a Python output port
907 * \param inport : input port to adapt to Python type type
908 * \param type : output port type
909 * \return an adaptated input port of type InputPyPort
911 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
912 TypeCode * type) throw (ConversionException)
914 if(inport->edGetType()->isAdaptable(type))
916 //the output data is convertible to inport type
917 return new PyXml(inport);
919 //non convertible type
921 msg << "Cannot connect Python output port with type: " << type->id() ;
922 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
924 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
926 throw ConversionException(msg.str());
929 //! Adapt a XML input port to a C++ output port
931 * \param inport : input port to adapt to C++ type type
932 * \param type : output port type
933 * \return an adaptated input port of type InputPyPort
935 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
936 TypeCode * type) throw (ConversionException)
938 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
939 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
940 if(type->isAdaptable(inport->edGetType()))
942 //the output data is convertible to inport type
943 return new CppXml(inport);
945 //non convertible type
947 msg << "Cannot connect Cpp output port with type: " << type->id() ;
948 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
950 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
952 throw ConversionException(msg.str());
955 //! Adapt a XML input port to a Neutral output port
957 * \param inport : input port to adapt to Neutral type type
958 * \param type : output port type
959 * \return an adaptated input port of type Neutralxxxx
961 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
962 TypeCode * type) throw (ConversionException)
964 if(inport->edGetType()->isAdaptable(type))
966 //the output data is convertible to inport type
967 return new NeutralXml(inport);
969 //non convertible type
971 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
972 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
973 throw ConversionException(msg.str());
976 //! Adapt a XML input port to a Xml output port
978 * \param inport : input port to adapt to Xml type type
979 * \param type : output port type
980 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
981 * \return an adaptated input port of type Xmlxxxx
983 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
984 TypeCode * type,bool init) throw (ConversionException)
987 return new ProxyPort(inport);
989 if(inport->edGetType()->isAdaptable(type))
990 return new ProxyPort(inport);
993 msg << "Cannot connect Xml output port with type: " << type->id() ;
994 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
996 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
998 throw ConversionException(msg.str());
1001 //! Adapt an Xml input port to an output port which implementation is given by impl
1003 * \param source : input port to adapt to implementation impl and type type
1004 * \param impl : output port implementation (C++, Python or Corba)
1005 * \param type : output port supported type
1006 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1007 * \return the adaptated port
1010 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1011 const std::string& impl,
1012 TypeCode * type,bool init) throw (ConversionException)
1014 if(impl == CORBANode::IMPL_NAME)
1016 return adaptXmlToCorba(source,type);
1018 else if(impl == PythonNode::IMPL_NAME)
1020 return adaptXmlToPython(source,type);
1022 else if(impl == CppNode::IMPL_NAME)
1024 return adaptXmlToCpp(source,type);
1026 else if(impl == XmlNode::IMPL_NAME )
1028 return adaptXmlToXml(source,type,init);
1030 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1032 return adaptXmlToNeutral(source,type);
1037 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1038 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1039 throw ConversionException(msg.str());
1044 //! Adapt a CORBA input port to a CORBA output port
1046 * \param inport : input port to adapt to CORBA outport data type
1047 * \param type : outport data type
1048 * \return an adaptator port of type InputCORBAPort
1050 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1051 TypeCode * type) throw (ConversionException)
1053 if(type->isA(inport->edGetType()))
1055 //types are compatible : no conversion
1056 //outport data type is more specific than inport required type
1057 //so the inport can be used safely
1058 return new ProxyPort(inport);
1060 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1062 //ouport data can be converted to inport data type
1063 return new CorbaCorba(inport);
1065 //outport data can not be converted
1067 msg << "Cannot connect Corba output port with type: " << type->id() ;
1068 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1070 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1072 throw ConversionException(msg.str());
1075 //! Adapt a CORBA input port to a Python output port
1077 * \param inport : input port to adapt to Python type type
1078 * \param type : outport data type
1079 * \return an adaptator port of type InputPyPort
1082 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1083 TypeCode * type) throw (ConversionException)
1085 if(inport->edGetType()->kind() == Double)
1087 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1089 else if(inport->edGetType()->kind() == Int)
1091 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1093 else if(inport->edGetType()->kind() == String)
1095 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1097 else if(inport->edGetType()->kind() == Bool)
1099 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1101 else if(inport->edGetType()->kind() == Objref )
1103 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1105 return new PyCorbaObjref(inport);
1110 msg << "Cannot connect Python output port with type: " << type->id() ;
1111 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1112 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1113 throw ConversionException(msg.str());
1116 else if(inport->edGetType()->kind() == Sequence)
1118 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1120 return new PyCorbaSequence(inport);
1125 msg << "Cannot convert this sequence type " ;
1126 msg << __FILE__ << ":" <<__LINE__;
1127 throw ConversionException(msg.str());
1130 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1132 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1134 return new PyCorbaStruct(inport);
1139 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1140 msg << __FILE__ << ":" <<__LINE__;
1141 throw ConversionException(msg.str());
1144 // Adaptation not possible
1146 msg << "Cannot connect Python output port with type: " << type->id() ;
1147 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1149 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1151 throw ConversionException(msg.str());
1154 //! Adapt a CORBA input port to connect it to a XML output port
1156 * \param inport : input port to adapt to Xml type type
1157 * \param type : type supported by output port
1158 * \return an adaptator port of type InputXmlPort
1161 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1162 TypeCode * type) throw (ConversionException)
1164 // BEWARE : using the generic check
1165 if(inport->edGetType()->isAdaptable(type))
1167 //output type is convertible to input type
1168 return new XmlCorba(inport);
1170 //output type is not convertible
1172 msg << "Cannot connect Xml output port with type: " << type->id() ;
1173 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1175 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1177 throw ConversionException(msg.str());
1180 //! Adapt a CORBA input port to a C++ output port
1182 * \param inport : input port to adapt to C++ type type
1183 * \param type : outport data type
1184 * \return an adaptator port of type InputCPPPort
1187 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1188 TypeCode * type) throw (ConversionException)
1190 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1191 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1193 //output type is convertible to input type
1194 return new CppCorba(inport);
1196 //output type is not convertible
1198 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1199 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1201 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1203 throw ConversionException(msg.str());
1206 //! Adapt a CORBA input port to a neutral data
1208 * \param inport : InputPort to adapt to Neutral type type
1209 * \param type : outport data type
1210 * \return an adaptator port of type Neutralxxxx
1213 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1214 TypeCode * type) throw (ConversionException)
1216 if(inport->edGetType()->kind() == Double)
1218 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1220 else if(inport->edGetType()->kind() == Int)
1222 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1224 else if(inport->edGetType()->kind() == String)
1226 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1228 else if(inport->edGetType()->kind() == Bool)
1230 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1232 else if(inport->edGetType()->kind() == Objref)
1234 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1236 else if(inport->edGetType()->kind() == Sequence)
1238 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1239 return new NeutralCorbaSequence(inport);
1243 msg << "Cannot convert this sequence type " ;
1244 msg << __FILE__ << ":" <<__LINE__;
1245 throw ConversionException(msg.str());
1248 else if(inport->edGetType()->kind() == Struct)
1250 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1253 // Adaptation not possible
1255 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1256 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1258 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1260 throw ConversionException(msg.str());
1263 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1265 * \param source : input port to adapt to implementation impl and type type
1266 * \param impl : output port implementation (C++, Python or Corba)
1267 * \param type : outport data type
1268 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1269 * \return an adaptator port which type depends on impl
1272 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1273 const std::string& impl,
1274 TypeCode * type,bool init) throw (ConversionException)
1276 if(impl == CppNode::IMPL_NAME)
1278 return adaptCorbaToCpp(source,type);
1280 else if(impl == PythonNode::IMPL_NAME)
1282 return adaptCorbaToPython(source,type);
1284 else if(impl == CORBANode::IMPL_NAME)
1287 return adaptCorbaToCorba(source,type);
1289 return adaptCorbaToCorba(source,type);
1291 else if(impl == XmlNode::IMPL_NAME )
1293 return adaptCorbaToXml(source,type);
1295 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1297 return adaptCorbaToNeutral(source,type);
1302 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1303 msg << __FILE__ << ":" <<__LINE__;
1304 throw ConversionException(msg.str());
1308 //! Adapt a Python input port to a Python output port
1310 * No need to make conversion or cast.
1311 * Only check, it's possible.
1312 * \param inport : InputPort to adapt to Python type type
1313 * \param type : outport data type
1314 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1315 * \return an adaptator port of type InputPyPort
1318 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1319 TypeCode * type,bool init) throw (ConversionException)
1322 return new PyInit(inport);
1324 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1326 //output data is convertible to input type
1327 //With python, no need to convert. Conversion will be done automatically
1328 //by the interpreter
1329 return new ProxyPort(inport);
1331 //output data is not convertible to input type
1333 msg << "Cannot connect Python output port with type: " << type->id() ;
1334 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1336 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1338 throw ConversionException(msg.str());
1341 //! Adapt a Python input port to a C++ output port
1343 * \param inport : InputPort to adapt to C++ type type
1344 * \param type : outport data type
1345 * \return an adaptator port of C++ type (InputCppPort)
1348 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1349 TypeCode * type) throw (ConversionException)
1351 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1352 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1354 //output type is convertible to input type
1355 return new CppPy(inport);
1357 //output type is not convertible
1359 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1360 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1362 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1364 throw ConversionException(msg.str());
1367 //! Adapt a Python input port to a Neutral data port
1369 * \param inport : InputPort to adapt to Neutral type type
1370 * \param type : outport data type
1371 * \return an adaptator port of Neutral type (Neutralxxxx)
1374 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1375 TypeCode * type) throw (ConversionException)
1377 if(inport->edGetType()->kind() == Double)
1379 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1381 else if(inport->edGetType()->kind() == Int)
1383 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1385 else if(inport->edGetType()->kind() == String)
1387 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1389 else if(inport->edGetType()->kind() == Bool)
1391 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1393 else if(inport->edGetType()->kind() == Objref)
1395 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1397 else if(inport->edGetType()->kind() == Sequence)
1399 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1400 return new NeutralPySequence(inport);
1404 msg << "Cannot convert this sequence type " ;
1405 msg << __FILE__ << ":" <<__LINE__;
1406 throw ConversionException(msg.str());
1409 else if(inport->edGetType()->kind() == Struct)
1411 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1414 // Adaptation not possible
1416 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1417 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1419 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1421 throw ConversionException(msg.str());
1424 //! Adapt a Python input port to a Corba output port
1426 * Always convert the data
1427 * \param inport : InputPort to adapt to Corba type type
1428 * \param type : outport data type
1429 * \return an adaptator port of Corba type (InputCorbaPort)
1432 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1433 TypeCode * type) throw (ConversionException)
1435 if(inport->edGetType()->kind() == Double)
1437 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1439 else if(inport->edGetType()->kind() == Int)
1441 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1443 else if(inport->edGetType()->kind() == String)
1445 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1447 else if(inport->edGetType()->kind() == Bool)
1449 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1451 else if(inport->edGetType()->kind() == Objref)
1453 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1455 return new CorbaPyObjref(inport);
1460 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1461 msg << " " << __FILE__ << ":" <<__LINE__;
1462 throw ConversionException(msg.str());
1465 else if(inport->edGetType()->kind() == Sequence)
1467 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1469 return new CorbaPySequence(inport);
1474 msg << "Cannot convert this sequence type " ;
1475 msg << __FILE__ << ":" <<__LINE__;
1476 throw ConversionException(msg.str());
1479 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1481 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1483 return new CorbaPyStruct(inport);
1488 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1489 msg << " " << __FILE__ << ":" <<__LINE__;
1490 throw ConversionException(msg.str());
1493 // Adaptation not possible
1495 msg << "Cannot connect Corba output port with type: " << type->id() ;
1496 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1498 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1500 throw ConversionException(msg.str());
1503 //! Adapt a Python input port to a Xml output port
1505 * \param inport : input port to adapt to Xml type type
1506 * \param type : output port type
1507 * \return an input port of type InputXmlPort
1510 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1511 TypeCode * type) throw (ConversionException)
1513 // BEWARE : using the generic check
1514 if(inport->edGetType()->isAdaptable(type))
1517 return new XmlPython(inport);
1519 //non convertible type
1521 msg << "Cannot connect Xml output port with type: " << type->id() ;
1522 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1524 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1526 throw ConversionException(msg.str());
1529 //! Adapt a Python input port to an output port with a given implementation
1531 * \param source : input port to adapt to implementation impl and type type
1532 * \param impl : output port implementation (C++, Python or Corba)
1533 * \param type : output port type
1534 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1535 * \return adaptated input port
1538 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1539 const std::string& impl,
1540 TypeCode * type,bool init) throw (ConversionException)
1542 if(impl == CppNode::IMPL_NAME)
1544 return adaptPythonToCpp(source,type);
1546 else if(impl == PythonNode::IMPL_NAME)
1548 return adaptPythonToPython(source,type,init);
1550 else if(impl == CORBANode::IMPL_NAME)
1552 return adaptPythonToCorba(source,type);
1554 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1556 return adaptPythonToNeutral(source,type);
1558 else if(impl == XmlNode::IMPL_NAME)
1560 return adaptPythonToXml(source,type);
1565 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1566 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1567 throw ConversionException(msg.str());
1572 //! Adapt a C++ input port to connect it to a CORBA output port
1574 * \param inport : input port to adapt to CORBA type type
1575 * \param type : type supported by output port
1576 * \return an adaptator port of type InputCorbaPort
1579 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1580 TypeCode * type) throw (ConversionException)
1582 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1583 if(isAdaptableCppCorba(type,inport->edGetType()))
1585 //output type is convertible to input type
1586 return new CorbaCpp(inport);
1588 //output type is not convertible
1590 msg << "Cannot connect Corba output port with type: " << type->id() ;
1591 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1593 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1595 throw ConversionException(msg.str());
1598 //! Adapt a C++ input port to a Python output port
1600 * \param inport : input port to adapt to Python type type
1601 * \param type : output port type
1602 * \return an adaptated input port of type InputPyPort
1604 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1605 TypeCode * type) throw (ConversionException)
1607 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1608 if(isAdaptableCppPyObject(type,inport->edGetType()))
1610 //output type is convertible to input type
1611 return new PyCpp(inport);
1613 //output type is not convertible
1615 msg << "Cannot connect Python output port with type: " << type->id() ;
1616 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1618 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1620 throw ConversionException(msg.str());
1623 //! Adapt a C++ input port to a C++ output port
1625 * \param inport : input port to adapt to C++ type type
1626 * \param type : output port type
1627 * \return an adaptated input port of type InputPyPort
1629 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1630 TypeCode * type) throw (ConversionException)
1632 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1633 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1634 if(type->isAdaptable(inport->edGetType()))
1636 //the output data is convertible to inport type
1637 return new CppCpp(inport);
1639 //non convertible type
1641 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1642 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1644 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1646 throw ConversionException(msg.str());
1649 //! Adapt a C++ input port to a Neutral output port
1651 * \param inport : input port to adapt to C++ type type
1652 * \param type : output port type
1653 * \return an adaptated input port of type InputPyPort
1655 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1656 TypeCode * type) throw (ConversionException)
1658 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1659 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1660 if(type->isAdaptable(inport->edGetType()))
1662 //the output data is convertible to inport type
1663 return new NeutralCpp(inport);
1665 //non convertible type
1667 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1668 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1670 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1672 throw ConversionException(msg.str());
1675 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1676 TypeCode * type) throw (ConversionException)
1678 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1679 if(isAdaptableCppXml(type,inport->edGetType()))
1682 return new XmlCpp(inport);
1684 //non convertible type
1686 msg << "Cannot connect Xml output port with type: " << type->id() ;
1687 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1689 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1691 throw ConversionException(msg.str());
1694 //! Adapt a C++ input port to connect it to an output port with a given implementation
1696 * \param source : input port to adapt to implementation impl and type type
1697 * \param impl : output port implementation (C++, Python or Corba)
1698 * \param type : output port supported type
1699 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1700 * \return the adaptated port
1703 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1704 const std::string& impl,
1705 TypeCode * type,bool init) throw (ConversionException)
1707 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1708 if(impl == CORBANode::IMPL_NAME)
1710 return adaptCppToCorba(source,type);
1712 else if(impl == PythonNode::IMPL_NAME)
1714 return adaptCppToPython(source,type);
1716 else if(impl == XmlNode::IMPL_NAME)
1718 return adaptCppToXml(source,type);
1720 else if(impl == CppNode::IMPL_NAME)
1722 return adaptCppToCpp(source, type);
1724 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1726 return adaptCppToNeutral(source, type);
1731 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1732 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1733 throw ConversionException(msg.str());
1737 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1738 // const InputPort* inputPort)
1740 // bool result=true;
1744 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1749 PyObject * RuntimeSALOME::getPyOrb()
1754 PyObject * RuntimeSALOME::getBuiltins()
1759 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1764 PyObject * RuntimeSALOME::get_omnipy()
1769 omniORBpyAPI* RuntimeSALOME::getApi()
1774 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1777 return (void *)convertNeutralPyObject(type,data);
1781 return (void *)Py_None;
1785 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1790 ob=convertNeutralPyObject(type,data);
1791 std::string s=convertPyObjectToString(ob);
1793 // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
1794 // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
1795 // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
1796 // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
1797 // feel free to change this code.
1798 PyGILState_STATE gstate = PyGILState_Ensure();
1800 PyGILState_Release(gstate);
1809 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1811 return YACS::ENGINE::convertPyObjectToString(ob);
1814 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1819 PyGILState_STATE gstate = PyGILState_Ensure();
1820 mainmod = PyImport_AddModule("__main__");
1821 globals = PyModule_GetDict(mainmod);
1822 PyObject* d = PyDict_New();
1823 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1824 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1830 PyObject* new_stderr = newPyStdOut(error);
1831 PySys_SetObject((char *)"stderr", new_stderr);
1833 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1834 Py_DECREF(new_stderr);
1835 PyGILState_Release(gstate);
1836 throw Exception(error);
1838 PyGILState_Release(gstate);