Salome HOME
Synchronize adm files
[modules/yacs.git] / src / runtime / CORBAPorts.cxx
1 // Copyright (C) 2006-2014  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //#define REFCNT
21 //
22 #ifdef REFCNT
23 #define private public
24 #define protected public
25 #include <omniORB4/CORBA.h>
26 #include <omniORB4/internal/typecode.h>
27 #endif
28
29 #include "RuntimeSALOME.hxx"
30 #include "TypeConversions.hxx"
31 #include "TypeCode.hxx"
32 #include "CORBAPorts.hxx"
33 #include "PythonPorts.hxx"
34 #include "ServiceNode.hxx"
35 #include "ComponentInstance.hxx"
36 #include "SALOME_GenericObj.hh"
37
38 #include <iostream>
39 #include <sstream>
40
41 //#define _DEVDEBUG_
42 #include "YacsTrace.hxx"
43
44 using namespace YACS::ENGINE;
45 using namespace std;
46
47 void releaseObj(CORBA::Any& data)
48 {
49   CORBA::Object_var obj;
50   if(data >>= CORBA::Any::to_object(obj))
51     {
52       SALOME::GenericObj_var gobj;
53       try
54         {
55           gobj=SALOME::GenericObj::_narrow(obj);
56         }
57       catch(const CORBA::SystemException& )
58         {
59           return;
60         }
61       if(!CORBA::is_nil(gobj))
62         {
63           DEBTRACE("It's a SALOME::GenericObj");
64           gobj->UnRegister();
65         }
66       else
67           DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj");
68     }
69   else
70     DEBTRACE("It's not a CORBA::Object");
71 }
72
73 void registerObj(CORBA::Any& data)
74 {
75   CORBA::Object_var obj;
76   if(data >>= CORBA::Any::to_object(obj))
77     {
78       SALOME::GenericObj_var gobj;
79       try
80         {
81           gobj=SALOME::GenericObj::_narrow(obj);
82         }
83       catch(const CORBA::SystemException& )
84         {
85           return;
86         }
87       if(!CORBA::is_nil(gobj))
88         {
89           DEBTRACE("It's a SALOME::GenericObj");
90           gobj->Register();
91         }
92       else
93           DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj");
94     }
95   else
96     DEBTRACE("It's not a CORBA::Object");
97 }
98
99 InputCorbaPort::InputCorbaPort(const std::string& name,
100                                Node *node,
101                                TypeCode * type)
102   : InputPort(name, node, type), DataPort(name, node, type), Port(node), _initData(0)
103 {
104   _orb = getSALOMERuntime()->getOrb();
105 }
106
107 InputCorbaPort::InputCorbaPort(const InputCorbaPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder),
108                                                                              _initData(0)
109 {
110   _orb = getSALOMERuntime()->getOrb();
111   if(other._initData)
112     {
113       _initData=new CORBA::Any;
114       *_initData=*(other._initData);
115     }
116   _data=other._data;
117 }
118
119 InputCorbaPort::~InputCorbaPort()
120 {
121   delete _initData;
122   // Release or not release : all GenericObj are deleted when the input port is deleted
123   releaseObj(_data);
124 }
125
126 bool InputCorbaPort::edIsManuallyInitialized() const
127 {
128   return _initData!=0;
129 }
130
131 void InputCorbaPort::edRemoveManInit()
132 {
133   delete _initData;
134   _initData=0;
135   InputPort::edRemoveManInit();
136 }
137
138 void InputCorbaPort::put(const void *data) throw (ConversionException)
139 {
140   put((CORBA::Any *)data);
141 }
142
143 void display(CORBA::Any* data)
144 {
145   CORBA::TypeCode_var tc=data->type();
146   switch(tc->kind())
147     {
148     case CORBA::tk_double:
149       CORBA::Double d;
150       *data >>= d;
151       DEBTRACE( "Double: " << d );
152       break;
153     case CORBA::tk_long:
154       CORBA::Long l;
155       *data >>= l;
156       DEBTRACE( "Int: " << l );
157       break;
158     default:
159       break;
160     }
161 }
162
163 void InputCorbaPort::put(CORBA::Any *data) throw (ConversionException)
164 {
165 #ifdef REFCNT
166   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
167 #endif
168   YACS::BASES::Lock lock(&_mutex);
169 #ifdef _DEVDEBUG_
170   display(data);
171 #endif
172
173   releaseObj(_data);
174
175   // make a copy of the any (protect against deletion of any source)
176   _data=*data;
177   _stringRef="";
178
179   registerObj(_data);
180
181 #ifdef REFCNT
182   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
183 #endif
184 }
185
186 InputPort *InputCorbaPort::clone(Node *newHelder) const
187 {
188   return new InputCorbaPort(*this,newHelder);
189 }
190
191 void *InputCorbaPort::get() const throw(YACS::Exception)
192 {
193   return (void *)&_data;
194 }
195
196 bool InputCorbaPort::isEmpty()
197 {
198   CORBA::TypeCode_var tc=_data.type();
199   return tc->equivalent(CORBA::_tc_null);
200 }
201
202 CORBA::Any * InputCorbaPort::getAny()
203 {
204   // --- return a pointer to internal any
205   return &_data;
206 }
207
208 PyObject * InputCorbaPort::getPyObj()
209 {
210   YACS::BASES::Lock lock(&_mutex);
211   CORBA::TypeCode_var tc=getAny()->type();
212   if (!tc->equivalent(CORBA::_tc_null))
213     return convertCorbaPyObject(edGetType(),getAny());
214   else
215     {
216       Py_INCREF(Py_None);
217       return Py_None;
218     }
219 }
220
221 std::string InputCorbaPort::getAsString()
222 {
223   InterpreterUnlocker loc;
224   PyObject* ob=getPyObj();
225   std::string s=convertPyObjectToString(ob);
226   Py_DECREF(ob);
227   return s;
228 }
229
230
231 //! Save the current data value for further reinitialization of the port
232 /*!
233  *
234  */
235 void InputCorbaPort::exSaveInit()
236 {
237   if(_initData)
238     delete _initData;
239   _initData=new CORBA::Any;
240   *_initData=_data;
241 }
242
243 //! Restore the saved data value to current data value
244 /*!
245  * If no data has been saved (_initData == 0) don't restore
246  */
247 void InputCorbaPort::exRestoreInit()
248 {
249   if(!_initData)return;
250   put(_initData);
251 }
252
253 std::string InputCorbaPort::dump()
254 {
255   CORBA::TypeCode_var tc=_data.type();
256   if (tc->equivalent(CORBA::_tc_null))
257     return "<value>nil</value>";
258   if (edGetType()->kind() != YACS::ENGINE::Objref)
259     return convertCorbaXml(edGetType(), &_data);
260   if (! _stringRef.empty())
261     return _stringRef;
262   else 
263     return convertCorbaXml(edGetType(), &_data);
264 //     {
265 //       stringstream msg;
266 //       msg << "Cannot retreive init string reference string for port " << _name
267 //           << " on node " << _node->getName();
268 //       throw Exception(msg.str());      
269 //     }
270 }
271
272 std::string InputCorbaPort::valToStr()
273 {
274   int isString = PyString_Check(getPyObj());
275   PyObject *strPyObj = PyObject_Str(getPyObj());
276   string val = PyString_AsString(strPyObj);
277   if (isString)
278     val = "\"" + val + "\"";
279   Py_DECREF(strPyObj);
280   return val;
281 }
282
283 void InputCorbaPort::valFromStr(std::string valstr)
284 {
285 }
286
287 OutputCorbaPort::OutputCorbaPort(const std::string& name,
288                                  Node *node,
289                                  TypeCode * type)
290   : OutputPort(name, node, type), DataPort(name, node, type), Port(node)
291 {
292   _orb = getSALOMERuntime()->getOrb();
293 }
294
295 OutputCorbaPort::OutputCorbaPort(const OutputCorbaPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder)
296 {
297   _orb = getSALOMERuntime()->getOrb();
298 }
299
300 OutputCorbaPort::~OutputCorbaPort()
301 {
302   DEBTRACE(getName());
303   // Release or not release : all GenericObj are deleted when the output port is deleted
304   releaseObj(_data);
305 #ifdef REFCNT
306   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
307   DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
308 #endif
309 }
310
311 void OutputCorbaPort::put(const void *data) throw (ConversionException)
312 {
313   put((CORBA::Any *)data);
314 }
315
316 void OutputCorbaPort::put(CORBA::Any *data) throw (ConversionException)
317 {
318   InputPort *p;
319
320   {  
321     YACS::BASES::Lock lock(&_mutex);
322 #ifdef REFCNT
323     DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
324 #endif
325 #ifdef REFCNT
326     DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
327 #endif
328
329     releaseObj(_data);
330
331     _data=*data;
332
333     //no registerObj : we steal the output reference of the node
334   }
335
336 #ifdef REFCNT
337   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
338 #endif
339   OutputPort::put(data);
340 #ifdef REFCNT
341   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
342 #endif
343 #ifdef REFCNT
344   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
345 #endif
346 }
347
348 OutputPort *OutputCorbaPort::clone(Node *newHelder) const
349 {
350   return new OutputCorbaPort(*this,newHelder);
351 }
352
353 CORBA::Any * OutputCorbaPort::getAny()
354 {
355   // return a pointer to the internal any
356   return &_data;
357 }
358
359 CORBA::Any * OutputCorbaPort::getAnyOut() 
360 {
361   CORBA::Any* a=new CORBA::Any;
362   DynType kind=edGetType()->kind();
363   CORBA::TypeCode_var t;
364
365   if(kind == Int)
366     {
367       a->replace(CORBA::_tc_long, (void*) 0);
368     }
369   else if(kind == String)
370     {
371       a->replace(CORBA::_tc_string, (void*) 0);
372     }
373   else if(kind == Double)
374     {
375       a->replace(CORBA::_tc_double, (void*) 0);
376     }
377   else if(kind == Objref)
378     {
379       t = getCorbaTC(edGetType());
380       a->replace(t, (void*) 0);
381     }
382   else if(kind == Sequence)
383     {
384       t = getCorbaTC(edGetType());
385       a->replace(t, (void*) 0);
386     }
387   else if(kind == Struct)
388     {
389       t = getCorbaTC(edGetType());
390 #ifdef REFCNT
391   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)t.in())->pd_ref_count);
392 #endif
393       a->replace(t, (void*) 0);
394 #ifdef REFCNT
395   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)t.in())->pd_ref_count);
396 #endif
397     }
398   else if(kind == Bool)
399     {
400       a->replace(CORBA::_tc_boolean, (void*) 0);
401     }
402   else if(kind == NONE)
403     {
404       stringstream msg;
405       msg << "Cannot set Any Out for None" << __FILE__ << ":" << __LINE__;
406       throw Exception(msg.str());
407     }
408   else
409     {
410       stringstream msg;
411       msg << "Cannot set Any Out for unknown type" << __FILE__
412           << ":" << __LINE__;
413       throw Exception(msg.str());
414     }
415     
416   DEBTRACE( "getAnyOut:a: " << a );
417 #ifdef REFCNT
418   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)a->pd_tc.in())->pd_ref_count);
419 #endif
420   return a;
421 }
422
423 PyObject * OutputCorbaPort::getPyObj()
424 {
425   YACS::BASES::Lock lock(&_mutex);
426   CORBA::TypeCode_var tc=getAny()->type();
427   if (!tc->equivalent(CORBA::_tc_null))
428     return convertCorbaPyObject(edGetType(),getAny());
429   else
430     {
431       Py_INCREF(Py_None);
432       return Py_None;
433     }
434 }
435
436 std::string OutputCorbaPort::getAsString()
437 {
438   InterpreterUnlocker loc;
439   PyObject* ob=getPyObj();
440   std::string s=convertPyObjectToString(ob);
441   Py_DECREF(ob);
442   return s;
443 }
444
445 std::string OutputCorbaPort::dump()
446 {
447   CORBA::TypeCode_var tc=_data.type();
448   if (tc->equivalent(CORBA::_tc_null))
449     return "<value>nil</value>";
450   string xmldump = convertCorbaXml(edGetType(), &_data);
451   return xmldump;
452 }
453 namespace YACS {
454   namespace ENGINE {
455     ostream& operator<<(ostream& os, const OutputCorbaPort& p)
456     {
457       CORBA::Double l;
458       p._data>>=l;
459       os << p._name << " : " << l ;
460       return os;
461     }
462   };
463 };
464
465 std::string OutputCorbaPort::valToStr()
466 {
467   PyObject *strPyObj = PyObject_Str(getPyObj());
468   string val = PyString_AsString(strPyObj);
469   Py_DECREF(strPyObj);
470   return val;
471 }
472
473 void OutputCorbaPort::valFromStr(std::string valstr)
474 {
475 }
476