1 // Copyright (C) 2006-2012 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.
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 "RuntimeSALOME.hxx"
32 #include "SALOMEDispatcher.hxx"
34 #include "TypeCode.hxx"
35 #include "WhileLoop.hxx"
36 #include "ForLoop.hxx"
37 #include "SalomeOptimizerLoop.hxx"
39 #include "InputPort.hxx"
40 #include "OutputPort.hxx"
41 #include "PresetPorts.hxx"
42 #include "InputDataStreamPort.hxx"
43 #include "OutputDataStreamPort.hxx"
44 #include "SalomeProc.hxx"
45 #include "PyStdout.hxx"
47 #include "SessionCataLoader.hxx"
50 #include "CORBAComponent.hxx"
51 #include "SalomeComponent.hxx"
52 #include "SalomePythonComponent.hxx"
53 #include "CppComponent.hxx"
55 #include "SalomeContainer.hxx"
56 #include "CppContainer.hxx"
59 #include "PythonNode.hxx"
60 #include "CORBANode.hxx"
61 #include "XMLNode.hxx"
62 #include "CppNode.hxx"
63 #include "PresetNode.hxx"
64 #include "OutNode.hxx"
65 #include "StudyNodes.hxx"
66 #include "SalomePythonNode.hxx"
67 #include "DistributedPythonNode.hxx"
70 #include "CORBACORBAConv.hxx"
71 #include "CORBAPythonConv.hxx"
72 #include "CORBAXMLConv.hxx"
73 #include "CORBACppConv.hxx"
74 #include "CORBANeutralConv.hxx"
76 #include "TypeConversions.hxx"
78 #include "PythonCORBAConv.hxx"
79 #include "PythonXMLConv.hxx"
80 #include "PythonCppConv.hxx"
81 #include "PythonNeutralConv.hxx"
82 #include "PythonInitConv.hxx"
85 #include "NeutralCORBAConv.hxx"
86 #include "NeutralPythonConv.hxx"
87 #include "NeutralXMLConv.hxx"
88 #include "NeutralCppConv.hxx"
89 #include "NeutralInitConv.hxx"
92 #include "CppCORBAConv.hxx"
93 #include "CppPythonConv.hxx"
94 #include "CppXMLConv.hxx"
95 #include "CppCppConv.hxx"
96 #include "CppNeutralConv.hxx"
99 #include "XMLCORBAConv.hxx"
100 #include "XMLPythonConv.hxx"
101 #include "XMLCppConv.hxx"
102 #include "XMLNeutralConv.hxx"
104 //Calcium specific ports
105 #include "CalStreamPort.hxx"
108 #include "SALOME_NamingService.hxx"
109 #include "SALOME_LifeCycleCORBA.hxx"
112 #include <libxml/parser.h>
113 #include <omniORB4/CORBA.h>
119 #include "YacsTrace.hxx"
122 using namespace YACS::ENGINE;
124 void RuntimeSALOME::setRuntime(long flags) // singleton creation (not thread safe!)
126 if (! Runtime::_singleton)
128 RuntimeSALOME* r=new RuntimeSALOME(flags);
129 Runtime::_singleton = r;
132 DEBTRACE("RuntimeSALOME::setRuntime() done !");
135 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
137 YASSERT(Runtime::_singleton);
138 return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
142 * Singleton creation, initialize converter map
145 RuntimeSALOME::RuntimeSALOME()
150 void RuntimeSALOME::initBuiltins()
152 //Fill the builtin catalog with nodes specific to the runtime
153 std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
154 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
155 std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
156 std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
157 nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
158 nodeMap["PyScript"]=new PythonNode("PyScript");
159 nodeMap["CORBANode"]=new CORBANode("CORBANode");
160 nodeMap["XmlNode"]=new XmlNode("XmlNode");
161 nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
162 nodeMap["CppNode"]=new CppNode("CppNode");
163 nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
164 nodeMap["PresetNode"]=new PresetNode("PresetNode");
165 nodeMap["OutNode"]=new OutNode("OutNode");
166 nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
167 nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
168 composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
169 typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
170 typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
171 typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
172 typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
173 typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
174 typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
175 typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
176 typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
177 std::list<TypeCodeObjref *> ltc;
178 typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
179 ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
180 t->addMember("ref",_tc_string);
181 typeMap["dataref"]= t;
184 RuntimeSALOME::RuntimeSALOME(long flags)
186 // If all flags (apart the IsPyExt flags) are unset, force them to true
187 if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
188 flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
189 + RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
191 // Salome Nodes implies Corba Nodes
192 if (flags & RuntimeSALOME::UseSalome)
193 flags |= RuntimeSALOME::UseCorba;
195 // Corba Nodes implies Python Nodes
196 if (flags & RuntimeSALOME::UseCorba)
197 flags |= RuntimeSALOME::UsePython;
199 _useCorba = flags & RuntimeSALOME::UseCorba;
200 _usePython = flags & RuntimeSALOME::UsePython;
201 _useCpp = flags & RuntimeSALOME::UseCpp;
202 _useXml = flags & RuntimeSALOME::UseXml;
207 if (_useCpp) _setOfImplementation.insert(CppNode::IMPL_NAME);
208 if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
209 if (_useCorba) _setOfImplementation.insert(CORBANode::IMPL_NAME);
210 if (_useXml) _setOfImplementation.insert(XmlNode::IMPL_NAME);
214 RuntimeSALOME::~RuntimeSALOME()
216 DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
217 // destroy catalog loader prototypes
218 std::map<std::string, CatalogLoader*>::const_iterator pt;
219 for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
225 //! CORBA and Python initialization
227 * \param flags contains several bits
228 * bit0 (ispyext) true when method is called from Python
229 * (Python initialization must not be done!)
230 * bit1 (UsePython) true if python nodes are needed
231 * bit1 (UseCorba) true if CORBA nodes are needed
232 * bit1 (UseXml) true if python nodes are needed
233 * bit1 (UseCpp) true if C++ nodes are needed
234 * bit1 (UseSalome) true if Salome nodes are needed
238 void RuntimeSALOME::init(long flags)
240 bool ispyext = flags & RuntimeSALOME::IsPyExt;
243 PortableServer::POA_var root_poa;
244 PortableServer::POAManager_var pman;
245 CORBA::Object_var obj;
246 int nbargs = 0; char **args = 0;
247 _orb = CORBA::ORB_init (nbargs, args);
248 obj = _orb->resolve_initial_references("RootPOA");
249 root_poa = PortableServer::POA::_narrow(obj);
250 pman = root_poa->the_POAManager();
254 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
256 obj = _orb->resolve_initial_references("DynAnyFactory");
257 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
262 DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
264 // Initialize Python interpreter in embedded mode
265 if (!Py_IsInitialized())
267 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
270 Py_InitializeEx(0); // do not install signal handlers
272 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
273 PyEval_SaveThread(); /* Release the thread state */
274 //here we do not have the Global Interpreter Lock
277 PyObject *mainmod,*pyapi,*res ;
279 PyGILState_STATE gstate;
280 gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
282 mainmod = PyImport_AddModule("__main__");
283 globals = PyModule_GetDict(mainmod);
284 /* globals is a borrowed reference */
286 if (PyDict_GetItemString(globals, "__builtins__") == NULL)
288 PyObject *bimod = PyImport_ImportModule("__builtin__");
289 if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
290 Py_FatalError("can't add __builtins__ to __main__");
294 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
300 _omnipy = PyImport_ImportModule((char*)"_omnipy");
304 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
307 pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
312 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
315 res=PyRun_String("\n"
316 "from math import *\n"
318 "sys.path.insert(0,'.')\n"
319 "from omniORB import CORBA\n"
320 "from omniORB import any\n"
321 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
322 "#print sys.getrefcount(orb)\n"
328 Py_file_input,globals,globals );
336 _pyorb = PyDict_GetItemString(globals,"orb");
337 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
340 pyany = PyDict_GetItemString(globals,"any");
341 /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
344 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
348 PyGILState_Release(gstate); // Release the Global Interpreter Lock
352 // initialize the catalogLoaderFactory map with the session one
353 _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
357 void RuntimeSALOME::fini()
361 PyGILState_STATE gstate = PyGILState_Ensure();
363 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
365 PyObject *mainmod, *globals;
366 mainmod = PyImport_AddModule("__main__");
367 globals = PyModule_GetDict(mainmod);
371 res=PyRun_String("orb.destroy()\n"
373 Py_file_input,globals,globals );
379 std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
380 delete nodeMap["PyFunction"];
381 delete nodeMap["PyScript"];
382 delete nodeMap["SalomePythonNode"];
383 nodeMap.erase("PyFunction");
384 nodeMap.erase("PyScript");
385 nodeMap.erase("SalomePythonNode");
389 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
397 DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
404 Proc* RuntimeSALOME::createProc(const std::string& name)
406 return new SalomeProc(name);
409 TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
410 std::list<TypeCodeObjref *> ltc)
413 if(id == "") myName = "IDL:" + name + ":1.0";
415 return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
418 TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
419 const std::string& name,
422 return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
425 TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
428 if(id == "") myName = "IDL:" + name + ":1.0";
430 return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
433 Bloc* RuntimeSALOME::createBloc(const std::string& name)
435 return new Bloc(name);
438 WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
440 return new WhileLoop(name);
443 ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
445 return new ForLoop(name);
448 OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
449 bool algInitOnFile, const std::string& kind, Proc * procForTypes)
451 OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
452 new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
453 ol->edGetNbOfBranchesPort()->edInit(1);
457 DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
462 node = new PresetNode(name);
465 else if(kind == "study" )
467 return new StudyInNode(name);
469 std::string msg="DataNode kind ("+kind+") unknown";
470 throw Exception(msg);
473 DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
477 return new OutNode(name);
479 else if(kind == "study" )
481 return new StudyOutNode(name);
484 std::string msg="OutDataNode kind ("+kind+") unknown";
485 throw Exception(msg);
488 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
490 InlineFuncNode* node;
491 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
493 node = new PyFuncNode(name);
496 if(kind == DistributedPythonNode::KIND)
497 return new DistributedPythonNode(name);
498 std::string msg="FuncNode kind ("+kind+") unknown";
499 throw Exception(msg);
502 InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
505 if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
507 node = new PythonNode(name);
510 std::string msg="ScriptNode kind ("+kind+") unknown";
511 throw Exception(msg);
514 ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
517 if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
519 node = new CORBANode(name);
522 else if(kind == XmlNode::KIND)
524 node = new XmlNode(name);
527 std::string msg="RefNode kind ("+kind+") unknown";
528 throw Exception(msg);
531 ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
534 if(kind == "" || kind == SalomeNode::KIND )
536 node=new SalomeNode(name);
539 else if (kind == CppNode::KIND)
541 node = new CppNode(name);
544 std::string msg="CompoNode kind ("+kind+") unknown";
545 throw Exception(msg);
548 ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
550 if(kind == "" || kind == SalomeNode::KIND )
551 return new SalomePythonNode(name);
552 std::string msg="CompoNode kind ("+kind+") unknown";
553 throw Exception(msg);
556 ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
557 const std::string& kind)
559 ComponentInstance* compo;
560 if(kind == "" || kind == SalomeComponent::KIND)
561 return new SalomeComponent(name);
562 else if(kind == CORBAComponent::KIND)
563 return new CORBAComponent(name);
564 else if(kind == SalomePythonComponent::KIND)
565 return new SalomePythonComponent(name);
566 else if (kind == CppComponent::KIND)
567 return new CppComponent(name);
568 std::string msg="Component Instance kind ("+kind+") unknown";
569 throw Exception(msg);
572 Container *RuntimeSALOME::createContainer(const std::string& kind)
574 if(kind == "" || kind == SalomeComponent::KIND)
575 return new SalomeContainer;
576 else if (kind == CppComponent::KIND)
577 return new CppContainer;
578 std::string msg="Container kind ("+kind+") unknown";
579 throw Exception(msg);
582 InputPort * RuntimeSALOME::createInputPort(const std::string& name,
583 const std::string& impl,
587 if(impl == CppNode::IMPL_NAME)
589 return new InputCppPort(name, node, type);
591 else if(impl == PythonNode::IMPL_NAME)
593 return new InputPyPort(name, node, type);
595 else if(impl == CORBANode::IMPL_NAME)
597 return new InputCorbaPort(name, node, type);
599 else if(impl == XmlNode::IMPL_NAME)
601 return new InputXmlPort(name, node, type);
606 msg << "Cannot create " << impl << " InputPort" ;
607 msg << " ("__FILE__ << ":" << __LINE__ << ")";
608 throw Exception(msg.str());
612 OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
613 const std::string& impl,
617 if(impl == CppNode::IMPL_NAME)
619 return new OutputCppPort(name, node, type);
621 else if(impl == PythonNode::IMPL_NAME)
623 return new OutputPyPort(name, node, type);
625 else if(impl == CORBANode::IMPL_NAME)
627 return new OutputCorbaPort(name, node, type);
629 else if(impl == XmlNode::IMPL_NAME)
631 return new OutputXmlPort(name, node, type);
636 msg << "Cannot create " << impl << " OutputPort" ;
637 msg << " ("__FILE__ << ":" << __LINE__ << ")";
638 throw Exception(msg.str());
642 InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
643 Node *node,TypeCode *type)
645 DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
646 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
648 return new InputCalStreamPort(name,node,type);
652 return new InputDataStreamPort(name,node,type);
656 OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
657 Node *node,TypeCode *type)
659 DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
660 if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
662 return new OutputCalStreamPort(name,node,type);
666 return new OutputDataStreamPort(name,node,type);
670 //! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation
672 * \param source : InputPort to be adapted
673 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
674 * \param type : data type provided by the InputPort
675 * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
677 * \return : adapted InputPort
679 InputPort* RuntimeSALOME::adapt(InputPort* source,
680 const std::string& impl,
681 TypeCode * type,bool init) throw (ConversionException)
683 string imp_source=source->getNode()->getImplementation();
684 if(imp_source == PythonNode::IMPL_NAME)
686 return adapt((InputPyPort*)source,impl,type,init);
688 else if(imp_source == CppNode::IMPL_NAME)
690 return adapt((InputCppPort*)source,impl,type,init);
692 else if(imp_source == CORBANode::IMPL_NAME)
694 return adapt((InputCorbaPort*)source,impl,type,init);
696 else if(imp_source == XmlNode::IMPL_NAME)
698 return adapt((InputXmlPort*)source,impl,type,init);
700 else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
702 return adaptNeutral(source,impl,type,init);
707 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
708 msg << " ("__FILE__ << ":" << __LINE__ << ")";
709 throw ConversionException(msg.str());
713 //! Adapter function for InPropertyPort
715 * \param source : InPropertyPort to be adapted
716 * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
717 * \param type : data type provided by the InPropertyPort
718 * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
720 * \return : adapted InputPort
722 InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
723 const std::string& impl,
724 TypeCode * type,bool init) throw (ConversionException)
726 return adaptNeutral((InputPort *)source,impl,type,init);
729 //! Adapt a Neutral input port to a Corba output port
731 * \param inport : Neutral input port to adapt to Corba type type
732 * \param type : output port type
733 * \return an adaptated input port of type InputCorbaPort
735 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
736 TypeCode * type) throw (ConversionException)
738 // BEWARE : using the generic check
739 if(inport->edGetType()->isAdaptable(type))
741 //the output data is convertible to inport type
742 return new CorbaNeutral(inport);
744 //non convertible type
746 msg << "Cannot connect Corba output port with type: " << type->id() ;
747 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
749 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
751 throw ConversionException(msg.str());
754 //! Adapt a Neutral input port to a Python output port
756 * \param inport : input port to adapt to Python type type
757 * \param type : output port type
758 * \return an adaptated input port of type InputPyPort
760 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
761 TypeCode * type) throw (ConversionException)
763 // BEWARE : using the generic check
764 if(inport->edGetType()->isAdaptable(type))
767 return new PyNeutral(inport);
769 //non convertible type
771 msg << "Cannot connect Python output port with type: " << type->id() ;
772 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
774 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
776 throw ConversionException(msg.str());
779 //! Adapt a Neutral input port to a Xml output port
781 * \param inport : input port to adapt to Xml type type
782 * \param type : output port type
783 * \return an input port of type InputXmlPort
785 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
786 TypeCode * type) throw (ConversionException)
788 // BEWARE : using the generic check
789 if(inport->edGetType()->isAdaptable(type))
792 return new XmlNeutral(inport);
794 //non convertible type
796 msg << "Cannot connect Xml output port with type: " << type->id() ;
797 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
799 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
801 throw ConversionException(msg.str());
804 //! Adapt a Neutral input port to a C++ output port
806 * \param inport : input port to adapt to C++ type type
807 * \param type : output port type
808 * \return an input port of type InputCppPort
810 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
811 TypeCode * type) throw (ConversionException)
813 DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
814 if(isAdaptableNeutralCpp(type,inport->edGetType()))
817 return new CppNeutral(inport);
819 //non convertible type
821 msg << "Cannot connect Cpp output port with type: " << type->id() ;
822 msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
824 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
826 throw ConversionException(msg.str());
829 //! Adapt a Neutral input port to connect it to an output port with a given implementation
831 * \param source : Neutral input port to adapt to implementation impl and type type
832 * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
833 * \param type : output port supported type
834 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
835 * \return the adaptated port
837 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
838 const std::string& impl,
839 TypeCode * type,bool init) throw (ConversionException)
841 if(impl == CppNode::IMPL_NAME)
843 return adaptNeutralToCpp(source,type);
845 else if(impl == PythonNode::IMPL_NAME)
847 return adaptNeutralToPython(source,type);
849 else if(impl == CORBANode::IMPL_NAME)
851 return adaptNeutralToCorba(source,type);
853 else if(impl == XmlNode::IMPL_NAME )
855 return adaptNeutralToXml(source,type);
857 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
860 return new NeutralInit(source);
862 return new ProxyPort(source);
865 msg << "Cannot connect InputPort : unknown implementation " << impl;
866 msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
867 throw ConversionException(msg.str());
870 //! Adapt a XML input port to connect it to a CORBA output port
872 * \param inport : input port to adapt to CORBA type type
873 * \param type : type supported by output port
874 * \return an adaptator port of type InputCorbaPort
877 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
878 TypeCode * type) throw (ConversionException)
880 if(isAdaptableXmlCorba(type,inport->edGetType()))
882 //output type is convertible to input type
883 return new CorbaXml(inport);
885 //output type is not convertible
887 msg << "Cannot connect Corba output port with type: " << type->id() ;
888 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
890 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
892 throw ConversionException(msg.str());
895 //! Adapt a XML input port to a Python output port
897 * \param inport : input port to adapt to Python type type
898 * \param type : output port type
899 * \return an adaptated input port of type InputPyPort
901 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
902 TypeCode * type) throw (ConversionException)
904 if(inport->edGetType()->isAdaptable(type))
906 //the output data is convertible to inport type
907 return new PyXml(inport);
909 //non convertible type
911 msg << "Cannot connect Python output port with type: " << type->id() ;
912 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
914 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
916 throw ConversionException(msg.str());
919 //! Adapt a XML input port to a C++ output port
921 * \param inport : input port to adapt to C++ type type
922 * \param type : output port type
923 * \return an adaptated input port of type InputPyPort
925 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
926 TypeCode * type) throw (ConversionException)
928 DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
929 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
930 if(type->isAdaptable(inport->edGetType()))
932 //the output data is convertible to inport type
933 return new CppXml(inport);
935 //non convertible type
937 msg << "Cannot connect Cpp output port with type: " << type->id() ;
938 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
940 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
942 throw ConversionException(msg.str());
945 //! Adapt a XML input port to a Neutral output port
947 * \param inport : input port to adapt to Neutral type type
948 * \param type : output port type
949 * \return an adaptated input port of type Neutralxxxx
951 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
952 TypeCode * type) throw (ConversionException)
954 if(inport->edGetType()->isAdaptable(type))
956 //the output data is convertible to inport type
957 return new NeutralXml(inport);
959 //non convertible type
961 msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
962 msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
963 throw ConversionException(msg.str());
966 //! Adapt a XML input port to a Xml output port
968 * \param inport : input port to adapt to Xml type type
969 * \param type : output port type
970 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
971 * \return an adaptated input port of type Xmlxxxx
973 InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
974 TypeCode * type,bool init) throw (ConversionException)
977 return new ProxyPort(inport);
979 if(inport->edGetType()->isAdaptable(type))
980 return new ProxyPort(inport);
983 msg << "Cannot connect Xml output port with type: " << type->id() ;
984 msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
986 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
988 throw ConversionException(msg.str());
991 //! Adapt an Xml input port to an output port which implementation is given by impl
993 * \param source : input port to adapt to implementation impl and type type
994 * \param impl : output port implementation (C++, Python or Corba)
995 * \param type : output port supported type
996 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
997 * \return the adaptated port
1000 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
1001 const std::string& impl,
1002 TypeCode * type,bool init) throw (ConversionException)
1004 if(impl == CORBANode::IMPL_NAME)
1006 return adaptXmlToCorba(source,type);
1008 else if(impl == PythonNode::IMPL_NAME)
1010 return adaptXmlToPython(source,type);
1012 else if(impl == CppNode::IMPL_NAME)
1014 return adaptXmlToCpp(source,type);
1016 else if(impl == XmlNode::IMPL_NAME )
1018 return adaptXmlToXml(source,type,init);
1020 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1022 return adaptXmlToNeutral(source,type);
1027 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
1028 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1029 throw ConversionException(msg.str());
1034 //! Adapt a CORBA input port to a CORBA output port
1036 * \param inport : input port to adapt to CORBA outport data type
1037 * \param type : outport data type
1038 * \return an adaptator port of type InputCORBAPort
1040 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
1041 TypeCode * type) throw (ConversionException)
1043 if(type->isA(inport->edGetType()))
1045 //types are compatible : no conversion
1046 //outport data type is more specific than inport required type
1047 //so the inport can be used safely
1048 return new ProxyPort(inport);
1050 else if(isAdaptableCorbaCorba(type,inport->edGetType()))
1052 //ouport data can be converted to inport data type
1053 return new CorbaCorba(inport);
1055 //outport data can not be converted
1057 msg << "Cannot connect Corba output port with type: " << type->id() ;
1058 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1060 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1062 throw ConversionException(msg.str());
1065 //! Adapt a CORBA input port to a Python output port
1067 * \param inport : input port to adapt to Python type type
1068 * \param type : outport data type
1069 * \return an adaptator port of type InputPyPort
1072 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
1073 TypeCode * type) throw (ConversionException)
1075 if(inport->edGetType()->kind() == Double)
1077 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
1079 else if(inport->edGetType()->kind() == Int)
1081 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
1083 else if(inport->edGetType()->kind() == String)
1085 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
1087 else if(inport->edGetType()->kind() == Bool)
1089 if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
1091 else if(inport->edGetType()->kind() == Objref )
1093 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1095 return new PyCorbaObjref(inport);
1100 msg << "Cannot connect Python output port with type: " << type->id() ;
1101 msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
1102 msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
1103 throw ConversionException(msg.str());
1106 else if(inport->edGetType()->kind() == Sequence)
1108 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1110 return new PyCorbaSequence(inport);
1115 msg << "Cannot convert this sequence type " ;
1116 msg << __FILE__ << ":" <<__LINE__;
1117 throw ConversionException(msg.str());
1120 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1122 if(isAdaptableCorbaPyObject(type,inport->edGetType()))
1124 return new PyCorbaStruct(inport);
1129 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1130 msg << __FILE__ << ":" <<__LINE__;
1131 throw ConversionException(msg.str());
1134 // Adaptation not possible
1136 msg << "Cannot connect Python output port with type: " << type->id() ;
1137 msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1139 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1141 throw ConversionException(msg.str());
1144 //! Adapt a CORBA input port to connect it to a XML output port
1146 * \param inport : input port to adapt to Xml type type
1147 * \param type : type supported by output port
1148 * \return an adaptator port of type InputXmlPort
1151 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
1152 TypeCode * type) throw (ConversionException)
1154 // BEWARE : using the generic check
1155 if(inport->edGetType()->isAdaptable(type))
1157 //output type is convertible to input type
1158 return new XmlCorba(inport);
1160 //output type is not convertible
1162 msg << "Cannot connect Xml output port with type: " << type->id() ;
1163 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1165 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1167 throw ConversionException(msg.str());
1170 //! Adapt a CORBA input port to a C++ output port
1172 * \param inport : input port to adapt to C++ type type
1173 * \param type : outport data type
1174 * \return an adaptator port of type InputCPPPort
1177 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
1178 TypeCode * type) throw (ConversionException)
1180 DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
1181 if(isAdaptableCorbaCpp(type,inport->edGetType()))
1183 //output type is convertible to input type
1184 return new CppCorba(inport);
1186 //output type is not convertible
1188 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1189 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1191 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1193 throw ConversionException(msg.str());
1196 //! Adapt a CORBA input port to a neutral data
1198 * \param inport : InputPort to adapt to Neutral type type
1199 * \param type : outport data type
1200 * \return an adaptator port of type Neutralxxxx
1203 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
1204 TypeCode * type) throw (ConversionException)
1206 if(inport->edGetType()->kind() == Double)
1208 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
1210 else if(inport->edGetType()->kind() == Int)
1212 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
1214 else if(inport->edGetType()->kind() == String)
1216 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
1218 else if(inport->edGetType()->kind() == Bool)
1220 if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
1222 else if(inport->edGetType()->kind() == Objref)
1224 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
1226 else if(inport->edGetType()->kind() == Sequence)
1228 if(isAdaptableCorbaNeutral(type,inport->edGetType()))
1229 return new NeutralCorbaSequence(inport);
1233 msg << "Cannot convert this sequence type " ;
1234 msg << __FILE__ << ":" <<__LINE__;
1235 throw ConversionException(msg.str());
1238 else if(inport->edGetType()->kind() == Struct)
1240 if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
1243 // Adaptation not possible
1245 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1246 msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1248 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1250 throw ConversionException(msg.str());
1253 //! Adapt a CORBA input port to an output which implementation and type are given by impl and type
1255 * \param source : input port to adapt to implementation impl and type type
1256 * \param impl : output port implementation (C++, Python or Corba)
1257 * \param type : outport data type
1258 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1259 * \return an adaptator port which type depends on impl
1262 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
1263 const std::string& impl,
1264 TypeCode * type,bool init) throw (ConversionException)
1266 if(impl == CppNode::IMPL_NAME)
1268 return adaptCorbaToCpp(source,type);
1270 else if(impl == PythonNode::IMPL_NAME)
1272 return adaptCorbaToPython(source,type);
1274 else if(impl == CORBANode::IMPL_NAME)
1277 return adaptCorbaToCorba(source,type);
1279 return adaptCorbaToCorba(source,type);
1281 else if(impl == XmlNode::IMPL_NAME )
1283 return adaptCorbaToXml(source,type);
1285 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1287 return adaptCorbaToNeutral(source,type);
1292 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
1293 msg << __FILE__ << ":" <<__LINE__;
1294 throw ConversionException(msg.str());
1298 //! Adapt a Python input port to a Python output port
1300 * No need to make conversion or cast.
1301 * Only check, it's possible.
1302 * \param inport : InputPort to adapt to Python type type
1303 * \param type : outport data type
1304 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1305 * \return an adaptator port of type InputPyPort
1308 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
1309 TypeCode * type,bool init) throw (ConversionException)
1312 return new PyInit(inport);
1314 if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
1316 //output data is convertible to input type
1317 //With python, no need to convert. Conversion will be done automatically
1318 //by the interpreter
1319 return new ProxyPort(inport);
1321 //output data is not convertible to input type
1323 msg << "Cannot connect Python output port with type: " << type->id() ;
1324 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1326 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1328 throw ConversionException(msg.str());
1331 //! Adapt a Python input port to a C++ output port
1333 * \param inport : InputPort to adapt to C++ type type
1334 * \param type : outport data type
1335 * \return an adaptator port of C++ type (InputCppPort)
1338 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
1339 TypeCode * type) throw (ConversionException)
1341 DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
1342 if(isAdaptablePyObjectCpp(type,inport->edGetType()))
1344 //output type is convertible to input type
1345 return new CppPy(inport);
1347 //output type is not convertible
1349 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1350 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1352 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1354 throw ConversionException(msg.str());
1357 //! Adapt a Python input port to a Neutral data port
1359 * \param inport : InputPort to adapt to Neutral type type
1360 * \param type : outport data type
1361 * \return an adaptator port of Neutral type (Neutralxxxx)
1364 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
1365 TypeCode * type) throw (ConversionException)
1367 if(inport->edGetType()->kind() == Double)
1369 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
1371 else if(inport->edGetType()->kind() == Int)
1373 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
1375 else if(inport->edGetType()->kind() == String)
1377 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
1379 else if(inport->edGetType()->kind() == Bool)
1381 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
1383 else if(inport->edGetType()->kind() == Objref)
1385 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
1387 else if(inport->edGetType()->kind() == Sequence)
1389 if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
1390 return new NeutralPySequence(inport);
1394 msg << "Cannot convert this sequence type " ;
1395 msg << __FILE__ << ":" <<__LINE__;
1396 throw ConversionException(msg.str());
1399 else if(inport->edGetType()->kind() == Struct)
1401 if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
1404 // Adaptation not possible
1406 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1407 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1409 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1411 throw ConversionException(msg.str());
1414 //! Adapt a Python input port to a Corba output port
1416 * Always convert the data
1417 * \param inport : InputPort to adapt to Corba type type
1418 * \param type : outport data type
1419 * \return an adaptator port of Corba type (InputCorbaPort)
1422 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
1423 TypeCode * type) throw (ConversionException)
1425 if(inport->edGetType()->kind() == Double)
1427 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
1429 else if(inport->edGetType()->kind() == Int)
1431 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
1433 else if(inport->edGetType()->kind() == String)
1435 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
1437 else if(inport->edGetType()->kind() == Bool)
1439 if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
1441 else if(inport->edGetType()->kind() == Objref)
1443 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1445 return new CorbaPyObjref(inport);
1450 msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
1451 msg << " " << __FILE__ << ":" <<__LINE__;
1452 throw ConversionException(msg.str());
1455 else if(inport->edGetType()->kind() == Sequence)
1457 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1459 return new CorbaPySequence(inport);
1464 msg << "Cannot convert this sequence type " ;
1465 msg << __FILE__ << ":" <<__LINE__;
1466 throw ConversionException(msg.str());
1469 else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
1471 if(isAdaptablePyObjectCorba(type,inport->edGetType()))
1473 return new CorbaPyStruct(inport);
1478 msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
1479 msg << " " << __FILE__ << ":" <<__LINE__;
1480 throw ConversionException(msg.str());
1483 // Adaptation not possible
1485 msg << "Cannot connect Corba output port with type: " << type->id() ;
1486 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1488 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1490 throw ConversionException(msg.str());
1493 //! Adapt a Python input port to a Xml output port
1495 * \param inport : input port to adapt to Xml type type
1496 * \param type : output port type
1497 * \return an input port of type InputXmlPort
1500 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
1501 TypeCode * type) throw (ConversionException)
1503 // BEWARE : using the generic check
1504 if(inport->edGetType()->isAdaptable(type))
1507 return new XmlPython(inport);
1509 //non convertible type
1511 msg << "Cannot connect Xml output port with type: " << type->id() ;
1512 msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1514 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1516 throw ConversionException(msg.str());
1519 //! Adapt a Python input port to an output port with a given implementation
1521 * \param source : input port to adapt to implementation impl and type type
1522 * \param impl : output port implementation (C++, Python or Corba)
1523 * \param type : output port type
1524 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1525 * \return adaptated input port
1528 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
1529 const std::string& impl,
1530 TypeCode * type,bool init) throw (ConversionException)
1532 if(impl == CppNode::IMPL_NAME)
1534 return adaptPythonToCpp(source,type);
1536 else if(impl == PythonNode::IMPL_NAME)
1538 return adaptPythonToPython(source,type,init);
1540 else if(impl == CORBANode::IMPL_NAME)
1542 return adaptPythonToCorba(source,type);
1544 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1546 return adaptPythonToNeutral(source,type);
1548 else if(impl == XmlNode::IMPL_NAME)
1550 return adaptPythonToXml(source,type);
1555 msg << "Cannot connect InputPyPort : unknown implementation " << impl;
1556 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1557 throw ConversionException(msg.str());
1562 //! Adapt a C++ input port to connect it to a CORBA output port
1564 * \param inport : input port to adapt to CORBA type type
1565 * \param type : type supported by output port
1566 * \return an adaptator port of type InputCorbaPort
1569 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
1570 TypeCode * type) throw (ConversionException)
1572 DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
1573 if(isAdaptableCppCorba(type,inport->edGetType()))
1575 //output type is convertible to input type
1576 return new CorbaCpp(inport);
1578 //output type is not convertible
1580 msg << "Cannot connect Corba output port with type: " << type->id() ;
1581 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1583 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1585 throw ConversionException(msg.str());
1588 //! Adapt a C++ input port to a Python output port
1590 * \param inport : input port to adapt to Python type type
1591 * \param type : output port type
1592 * \return an adaptated input port of type InputPyPort
1594 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
1595 TypeCode * type) throw (ConversionException)
1597 DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
1598 if(isAdaptableCppPyObject(type,inport->edGetType()))
1600 //output type is convertible to input type
1601 return new PyCpp(inport);
1603 //output type is not convertible
1605 msg << "Cannot connect Python output port with type: " << type->id() ;
1606 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1608 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1610 throw ConversionException(msg.str());
1613 //! Adapt a C++ input port to a C++ output port
1615 * \param inport : input port to adapt to C++ type type
1616 * \param type : output port type
1617 * \return an adaptated input port of type InputPyPort
1619 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
1620 TypeCode * type) throw (ConversionException)
1622 DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
1623 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1624 if(type->isAdaptable(inport->edGetType()))
1626 //the output data is convertible to inport type
1627 return new CppCpp(inport);
1629 //non convertible type
1631 msg << "Cannot connect Cpp output port with type: " << type->id() ;
1632 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1634 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1636 throw ConversionException(msg.str());
1639 //! Adapt a C++ input port to a Neutral output port
1641 * \param inport : input port to adapt to C++ type type
1642 * \param type : output port type
1643 * \return an adaptated input port of type InputPyPort
1645 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
1646 TypeCode * type) throw (ConversionException)
1648 DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
1649 DEBTRACE(type->kind() << " " << inport->edGetType()->kind() );
1650 if(type->isAdaptable(inport->edGetType()))
1652 //the output data is convertible to inport type
1653 return new NeutralCpp(inport);
1655 //non convertible type
1657 msg << "Cannot connect Neutral output port with type: " << type->id() ;
1658 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1660 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1662 throw ConversionException(msg.str());
1665 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
1666 TypeCode * type) throw (ConversionException)
1668 DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
1669 if(isAdaptableCppXml(type,inport->edGetType()))
1672 return new XmlCpp(inport);
1674 //non convertible type
1676 msg << "Cannot connect Xml output port with type: " << type->id() ;
1677 msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
1679 msg << " ("<<__FILE__ << ":" << __LINE__<<")";
1681 throw ConversionException(msg.str());
1684 //! Adapt a C++ input port to connect it to an output port with a given implementation
1686 * \param source : input port to adapt to implementation impl and type type
1687 * \param impl : output port implementation (C++, Python or Corba)
1688 * \param type : output port supported type
1689 * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
1690 * \return the adaptated port
1693 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
1694 const std::string& impl,
1695 TypeCode * type,bool init) throw (ConversionException)
1697 DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
1698 if(impl == CORBANode::IMPL_NAME)
1700 return adaptCppToCorba(source,type);
1702 else if(impl == PythonNode::IMPL_NAME)
1704 return adaptCppToPython(source,type);
1706 else if(impl == XmlNode::IMPL_NAME)
1708 return adaptCppToXml(source,type);
1710 else if(impl == CppNode::IMPL_NAME)
1712 return adaptCppToCpp(source, type);
1714 else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
1716 return adaptCppToNeutral(source, type);
1721 msg << "Cannot connect InputCppPort to " << impl << " implementation";
1722 msg << " ("__FILE__ << ":" << __LINE__ << ")";
1723 throw ConversionException(msg.str());
1727 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
1728 // const InputPort* inputPort)
1730 // bool result=true;
1734 CORBA::ORB_ptr RuntimeSALOME::getOrb()
1739 PyObject * RuntimeSALOME::getPyOrb()
1744 PyObject * RuntimeSALOME::getBuiltins()
1749 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
1754 PyObject * RuntimeSALOME::get_omnipy()
1759 omniORBpyAPI* RuntimeSALOME::getApi()
1764 void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
1767 return (void *)convertNeutralPyObject(type,data);
1771 return (void *)Py_None;
1775 std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
1780 ob=convertNeutralPyObject(type,data);
1781 std::string s=convertPyObjectToString(ob);
1791 std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
1793 return YACS::ENGINE::convertPyObjectToString(ob);
1796 PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
1801 PyGILState_STATE gstate = PyGILState_Ensure();
1802 mainmod = PyImport_AddModule("__main__");
1803 globals = PyModule_GetDict(mainmod);
1804 PyObject* d = PyDict_New();
1805 //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1806 ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
1812 PyObject* new_stderr = newPyStdOut(error);
1813 PySys_SetObject((char *)"stderr", new_stderr);
1815 PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
1816 Py_DECREF(new_stderr);
1817 PyGILState_Release(gstate);
1818 throw Exception(error);
1820 PyGILState_Release(gstate);