2 #include "RuntimeSALOME.hxx"
3 #include "PythonNode.hxx"
4 #include "CORBANode.hxx"
7 #include "TypeConversions.hxx"
8 #include "CORBACORBAConv.hxx"
9 #include "PythonCORBAConv.hxx"
10 #include "CORBAPythonConv.hxx"
11 #include "XMLCORBAConv.hxx"
13 #include <omniORB4/CORBA.h>
19 using namespace YACS::ENGINE;
23 void RuntimeSALOME::setRuntime() // singleton creation (not thread safe!)
25 if (! Runtime::_singleton) Runtime::_singleton = new RuntimeSALOME();
28 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
30 assert(Runtime::_singleton);
31 return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
35 * Singleton creation, initialize converter map
38 RuntimeSALOME::RuntimeSALOME()
40 _setOfImplementation.insert("Cpp");
41 _setOfImplementation.insert("Python");
42 _setOfImplementation.insert("CORBA");
47 void RuntimeSALOME::init()
49 int nbargs = 0; char **args = 0;
50 _orb = CORBA::ORB_init (nbargs, args);
51 CORBA::Object_var obj = _orb->resolve_initial_references("DynAnyFactory");
52 _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
55 cerr << "RuntimeSALOME::init" << endl;
58 mainmod = PyImport_AddModule("__main__");
60 globals = PyModule_GetDict(mainmod);
62 /* globals is a borrowed reference */
64 /* globals is a new reference */
66 _bltins = PyEval_GetBuiltins(); /* borrowed ref */
69 PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy");
72 PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
75 PyObject* pyapi = PyObject_GetAttrString(omnipy, (char*)"API");
76 _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
78 PyObject *res=PyRun_String("\n"
80 "sys.path.insert(0,'.')\n"
82 "from omniORB import any\n"
83 "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
84 "print sys.getrefcount(orb)\n"
86 Py_file_input,globals,globals );
93 _pyorb = PyDict_GetItemString(globals,"orb");
94 cerr << "refcnt: " << _pyorb->ob_refcnt << endl;
95 PyObject_Print(_pyorb,stdout,Py_PRINT_RAW);
97 /* pyorb is a borrowed reference */
98 //Py_INCREF(pyorb); pas nécessaire
101 pyany = PyDict_GetItemString(globals,"any");
102 cerr << "pyany refcnt: " << pyany->ob_refcnt << endl;
103 /* pyany is a borrowed reference */
107 void RuntimeSALOME::fini()
109 cerr << "RuntimeSALOME::fini" << endl;
114 ElementaryNode* RuntimeSALOME::createNode(string implementation,
115 string name) throw(Exception)
117 ElementaryNode* node = 0;
118 if (implementation == "Python")
119 node = new PythonNode(name);
120 else if (implementation == "CORBA")
121 node = new CORBANode(name);
122 else if (implementation == "XML")
123 node = new XmlNode(name);
124 else if (implementation == "Cpp")
125 node = new CppNode(name);
128 string what ="RuntimeSALOME does not handle this implementation: " + implementation;
129 throw Exception(what);
134 InputPort * RuntimeSALOME::createInputPort(const string& name,
141 throw Exception("Cannot create InputCppPort ");
143 else if(impl == "Python")
145 return new InputPyPort(name, node, type);
147 else if(impl == "CORBA")
149 return new InputCorbaPort(name, node, type);
151 else if(impl == "XML")
153 return new InputXmlPort(name, node, type);
158 msg << "Cannot create " << impl << " InputPort" ;
159 msg << " ("__FILE__ << ":" << __LINE__ << ")";
160 throw Exception(msg.str());
164 OutputPort * RuntimeSALOME::createOutputPort(const string& name,
171 throw Exception("Cannot create OutputCppPort ");
173 else if(impl == "Python")
175 return new OutputPyPort(name, node, type);
177 else if(impl == "CORBA")
179 return new OutputCorbaPort(name, node, type);
181 else if(impl == "XML")
183 return new OutputXmlPort(name, node, type);
188 msg << "Cannot create " << impl << " OutputPort" ;
189 msg << " ("__FILE__ << ":" << __LINE__ << ")";
190 throw Exception(msg.str());
194 InputPort* RuntimeSALOME::adapt(const string& imp_source,
197 TypeCode * type) throw (ConversionException)
199 cerr<<"RuntimeSALOME::adapt(InputPort* source" << endl;
200 if(imp_source == "Python")
202 return adapt((InputPyPort*)source,impl,type);
204 else if(imp_source == "CORBA")
206 return adapt((InputCorbaPort*)source,impl,type);
208 else if(imp_source == "XML")
210 return adapt((InputXmlPort*)source,impl,type);
215 msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
216 msg << " ("__FILE__ << ":" << __LINE__ << ")";
217 throw ConversionException(msg.str());
221 //! Retourne un adaptateur d'un port entrant Xml pour un port sortant dont l'implémentation est donnée par impl
223 * \param source : input port to adapt to implementation impl and type type
224 * \param impl : output port implementation (C++, Python or Corba)
225 * \param type : le type supporté par le port sortant
226 * \return input port adapté à l'implémentation
229 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
231 TypeCode * type) throw (ConversionException)
233 cerr<<"RuntimeSALOME::adapt(InputXmlPort* source" << endl;
236 return adaptXmlToCorba(source,type);
241 msg << "Cannot connect InputXmlPort to " << impl << " implementation";
242 msg << " ("__FILE__ << ":" << __LINE__ << ")";
243 throw ConversionException(msg.str());
247 //! Retourne un adaptateur d'un port entrant XML pour un port sortant CORBA
249 * \param inport : input port to adapt to CORBA type type
250 * \param type : le type supporté par le port sortant
251 * \return a InputCorbaPort port
254 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
255 TypeCode * type) throw (ConversionException)
257 cerr <<"RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport" << endl;
258 if(isAdaptableXmlCorba(type,inport->type()))
260 //les types sont convertibles
261 return new CorbaXml(inport);
263 //les types sont non convertibles
265 msg << "Cannot connect InputXmlPort to Corba output port " ;
266 msg << type->id() << " != " << inport->type()->id();
267 msg << " ("__FILE__ << ":" << __LINE__ << ")";
268 throw ConversionException(msg.str());
271 //! Retourne un adaptateur d'un port entrant CORBA pour un port sortant Xml
273 * \param inport : input port to adapt to Xml type type
274 * \param type : le type supporté par le port sortant
275 * \return an input port of Python type InputXmlPort
278 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
279 TypeCode * type) throw (ConversionException)
281 //ATTENTION : on utilise isAdaptableCorbaPyObject (meme fonction)
282 cerr << "RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport" << endl;
283 if(isAdaptableCorbaPyObject(type,inport->type()))
285 //les types sont convertibles
286 return new XmlCorba(inport);
288 //les types sont non convertibles
290 msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ;
291 msg << __FILE__ << ":" <<__LINE__;
292 throw ConversionException(msg.str());
296 //! Retourne un adaptateur d'un port entrant CORBA pour un port sortant CORBA
298 * \param inport : input port to adapt to CORBA type type
299 * \param type : le type supporté par le port sortant
302 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
303 TypeCode * type) throw (ConversionException)
305 if(type->is_a(inport->type()))
307 //les types sont compatibles : pas de conversion
310 else if(isAdaptableCorbaCorba(type,inport->type()))
312 //les types sont convertibles
313 return new CorbaCorba(inport);
315 //les types sont non convertibles
317 msg << "Cannot connect 2 CorbaPort with non convertible types: " ;
318 msg << type->id() << " != " << inport->type()->id();
319 throw ConversionException(msg.str());
322 //! Retourne un adaptateur d'un port entrant CORBA pour un port sortant Python
324 * \param inport : input port to adapt to Python type type
325 * \param type : le type supporté par le port sortant
326 * \return an input port of Python type InputPyPort
329 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
330 TypeCode * type) throw (ConversionException)
332 if(inport->type()->kind() == Double)
334 if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaDouble(inport);
336 else if(inport->type()->kind() == Int)
338 if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaInt(inport);
340 else if(inport->type()->kind() == String)
342 if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaString(inport);
344 else if(inport->type()->kind() == Objref )
346 if(isAdaptableCorbaPyObject(type,inport->type()))
348 return new PyCorbaObjref(inport);
353 msg << "Cannot connect InputPyPort : incompatible objref types ";
354 msg << __FILE__ << ":" <<__LINE__;
355 throw ConversionException(msg.str());
358 else if(inport->type()->kind() == Sequence)
360 if(isAdaptableCorbaPyObject(type,inport->type()))
362 return new PyCorbaSequence(inport);
367 msg << "Cannot convert this sequence type " ;
368 msg << __FILE__ << ":" <<__LINE__;
369 throw ConversionException(msg.str());
372 // Adaptation not found
374 msg << "Cannot connect InputCorbaPort to Python output " ;
375 msg << __FILE__ << ":" <<__LINE__;
376 throw ConversionException(msg.str());
379 //! Retourne un adaptateur d'un port entrant CORBA pour un port sortant C++
381 * \param inport : input port to adapt to C++ type type
382 * \param type : le type supporté par le port sortant
385 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
386 TypeCode * type) throw (ConversionException)
388 throw ConversionException("Cannot connect InputCorbaPort to C++ ");
391 //! Retourne un adaptateur d'un port entrant CORBA pour un port sortant dont l'implémentation est donnée par impl
393 * \param source : input port to adapt to implementation impl and type type
394 * \param impl : output port implementation (C++, Python or Corba)
395 * \param type : le type supporté par le port sortant
398 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
400 TypeCode * type) throw (ConversionException)
402 cerr<<"RuntimeSALOME::adapt(InputPyPort* source" << endl;
405 return adaptCorbaToCpp(source,type);
407 else if(impl == "Python")
409 return adaptCorbaToPython(source,type);
411 else if(impl == "CORBA")
413 return adaptCorbaToCorba(source,type);
415 else if(impl == "XML")
417 return adaptCorbaToXml(source,type);
422 msg << "Cannot connect InputCorbaPort : unknown implementation " ;
423 msg << __FILE__ << ":" <<__LINE__;
424 throw ConversionException(msg.str());
429 //! Retourne un adaptateur d'un port entrant Python pour un port sortant Python
431 * Dans ce cas, on ne fait pas de conversion ni de cast (int->double, par ex).
432 * On vérifie simplement que la connexion est autorisée.
433 * \param inport : InputPort to adapt to Python type type
434 * \param type : le TypeCode supporté par le port sortant
435 * \return InputPort de type Python (InputPyPort)
438 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
439 TypeCode * type) throw (ConversionException)
441 if(isAdaptablePyObjectPyObject(type,inport->type()))
443 //les types sont convertibles
444 //En Python, il n'est pas nécessaire de convertir. La conversion
445 //sera faite à la volée dans l'interpréteur
448 //les types sont non convertibles
450 msg << "Cannot connect 2 Python Port with non convertible types: " ;
451 msg << type->id() << " != " << inport->type()->id();
452 throw ConversionException(msg.str());
455 //! Retourne un adaptateur d'un port entrant Python pour un port sortant C++
457 * Pas encore implémenté
458 * \param inport : InputPort to adapt to C++ type type
459 * \param type : le TypeCode supporté par le port sortant
460 * \return InputPort de type C++ (InputCppPort)
463 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
464 TypeCode * type) throw (ConversionException)
466 throw ConversionException("Cannot connect InputPyPort to C++ ");
469 //! Retourne un adaptateur d'un port entrant Python pour un port sortant Corba
471 * On convertit dans tous les cas
472 * \param inport : InputPort to adapt to Corba type type
473 * \param type : le TypeCode supporté par le port sortant
474 * \return InputPort de type Corba (InputCorbaPort)
477 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
478 TypeCode * type) throw (ConversionException)
480 cerr << "RuntimeSALOME::adaptPythonToCorba:" ;
481 cerr << inport->type()->kind() << ":" << type->kind()<< endl;
483 if(inport->type()->kind() == Double)
485 if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyDouble(inport);
487 else if(inport->type()->kind() == Int)
489 if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyInt(inport);
491 else if(inport->type()->kind() == String)
493 if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyString(inport);
495 else if(inport->type()->kind() == Objref)
497 if(isAdaptablePyObjectCorba(type,inport->type()))
499 return new CorbaPyObjref(inport);
504 msg << "Cannot connect InputCorbaPort : incompatible objref types ";
505 msg << __FILE__ << ":" <<__LINE__;
506 throw ConversionException(msg.str());
509 else if(inport->type()->kind() == Sequence)
511 if(isAdaptablePyObjectCorba(type,inport->type()))
513 return new CorbaPySequence(inport);
518 msg << "Cannot convert this sequence type " ;
519 msg << __FILE__ << ":" <<__LINE__;
520 throw ConversionException(msg.str());
523 // Adaptation not found
525 msg << "Cannot connect InputPyPort to Corba output " ;
526 msg << __FILE__ << ":" << __LINE__;
527 throw ConversionException(msg.str());
530 //! Retourne un adaptateur d'un port entrant Python pour un port sortant dont l'implémentation est donnée par impl
532 * \param source : input port to adapt to implementation impl and type type
533 * \param impl : output port implementation (C++, Python or Corba)
534 * \param type : le type supporté par le port sortant
535 * \return input port adapté à l'implémentation
538 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
540 TypeCode * type) throw (ConversionException)
542 cerr<<"RuntimeSALOME::adapt(InputPyPort* source" << endl;
545 return adaptPythonToCpp(source,type);
547 else if(impl == "Python")
549 return adaptPythonToPython(source,type);
551 else if(impl == "CORBA")
553 return adaptPythonToCorba(source,type);
557 throw ConversionException("Cannot connect InputPyPort : unknown implementation ");
561 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort,
562 // const InputPort* inputPort)
568 CORBA::ORB_ptr RuntimeSALOME::getOrb()
573 PyObject * RuntimeSALOME::getPyOrb()
578 PyObject * RuntimeSALOME::getBuiltins()
583 DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
588 omniORBpyAPI* RuntimeSALOME::getApi()