Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / runtime / CORBANode.cxx
1
2 //#define REFCNT
3 #ifdef REFCNT
4 #define private public
5 #define protected public
6 #include <omniORB4/CORBA.h>
7 #include <omniORB4/internal/typecode.h>
8 #endif
9
10 #include "RuntimeSALOME.hxx"
11 #include "CORBANode.hxx"
12 #include "CORBAComponent.hxx"
13 #include "SalomeComponent.hxx"
14 #include "CORBAPorts.hxx"
15 #include "OutputDataStreamPort.hxx"
16 #include "CalStreamPort.hxx"
17 #include "InPort.hxx"
18
19 #ifdef SALOME_KERNEL
20 #include "SALOME_NamingService.hxx"
21 #include "SALOME_LifeCycleCORBA.hxx"
22 #endif
23
24 #include <omniORB4/CORBA.h>
25 #include <iostream>
26 #include <set>
27 #include <list>
28
29 //#define _DEVDEBUG_
30 #include "YacsTrace.hxx"
31
32 using namespace YACS::ENGINE;
33 using namespace std;
34
35 const char CORBANode::IMPL_NAME[]="CORBA";
36 const char CORBANode::KIND[]="CORBA";
37
38 std::string CORBANode::getKind() const
39 {
40   return KIND;
41 }
42
43 //! CORBANode constructor
44 CORBANode::CORBANode(const std::string& name): ServiceNode(name)
45 {
46   _implementation=IMPL_NAME;
47 }
48
49 CORBANode::CORBANode(const CORBANode& other,ComposedNode *father):ServiceNode(other,father)
50 {
51   _implementation=IMPL_NAME;
52 }
53
54 //! Execute the service on the component associated to the node
55 void CORBANode::execute()
56 {
57   DEBTRACE( "+++++++++++++ CorbaNode::execute: " << getName() << " +++++++++++++++" );
58   {
59     //DII request building :
60     // a service gets all its in parameters first
61     // then all its out parameters
62     // no inout parameters
63     // the return value (if any) is the first out parameter
64     // not yet user exception (only CORBA exception)
65
66     CORBA::Object_var objComponent=((CORBAComponent*)_component)->getCompoPtr();
67     CORBA::Request_var req = objComponent->_request(_method.c_str());
68     CORBA::NVList_ptr arguments = req->arguments() ;
69
70     DEBTRACE( "+++++++++++++++++CorbaNode::inputs+++++++++++++++++" )
71     int in_param=0;
72     //in parameters
73     list<InputPort *>::iterator iter2;
74     for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
75       {
76         InputCorbaPort *p=(InputCorbaPort *)*iter2;
77         DEBTRACE( "port name: " << p->getName() )
78         DEBTRACE( "port kind: " << p->edGetType()->kind() )
79         CORBA::Any* ob=p->getAny();
80 #ifdef _DEVDEBUG_
81         CORBA::TypeCode_var typcod= ob->type();
82         switch(p->edGetType()->kind())
83           {
84           case Double:
85             CORBA::Double d;
86             *ob >>= d;
87             DEBTRACE( d )
88             break;
89           case Int:
90             CORBA::Long l;
91             *ob >>= l;
92             DEBTRACE( l )
93             break;
94           case String:
95             const char *s;
96             *ob >>= s;
97             DEBTRACE( s )
98             break;
99           case Bool:
100             CORBA::Boolean b;
101             if(*ob >>= CORBA::Any::to_boolean(b))
102               DEBTRACE( b )
103             else 
104               DEBTRACE( "not a boolean" )
105             break;
106           case Objref:
107             DEBTRACE( typcod->id() )
108             break;
109           default:
110             break;
111           }
112 #endif
113         //add_value makes a copy of any (*ob). This copy will be deleted with the request
114         arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_IN ) ;
115         in_param=in_param+1;
116       }
117     
118     //output parameters
119     DEBTRACE( "+++++++++++++++++CorbaNode::outputs+++++++++++++++++" )
120     list<OutputPort *>::iterator iter;
121     for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
122       {
123         OutputCorbaPort *p=(OutputCorbaPort *)*iter;
124         DEBTRACE( "port name: " << p->getName() )
125         DEBTRACE( "port kind: " << p->edGetType()->kind() )
126         CORBA::Any* ob=p->getAnyOut();
127 #ifdef REFCNT
128         DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
129 #endif
130         //add_value makes a copy of any. Copy will be deleted with request
131         arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_OUT );
132 #ifdef REFCNT
133         DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
134 #endif
135       }
136
137     //return value
138     req->set_return_type(CORBA::_tc_void);
139     //user exceptions
140     //req->exceptions()->add(eo::_tc_SALOME_Exception);
141     
142     DEBTRACE( "+++++++++++++++++CorbaNode::calculation+++++++++++++++++" << _method )
143     req->invoke();
144     CORBA::Exception *exc =req->env()->exception();
145     if( exc )
146       {
147         DEBTRACE( "An exception was thrown!" )
148         DEBTRACE( "The raised exception is of Type:" << exc->_name() )
149         throw Exception("Execution problem");
150       }
151     
152     DEBTRACE( "++++++++++++CorbaNode::outputs++++++++++++" )
153     int out_param=in_param;
154     for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
155       {
156         OutputCorbaPort *p=(OutputCorbaPort *)*iter;
157         DEBTRACE( "port name: " << p->getName() )
158         DEBTRACE( "port kind: " << p->edGetType()->kind() )
159         DEBTRACE( "port number: " << out_param )
160         CORBA::Any *ob=arguments->item(out_param)->value();
161 #ifdef REFCNT
162         DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
163 #endif
164 #ifdef _DEVDEBUG_
165         CORBA::TypeCode_var tc=ob->type();
166         switch(p->edGetType()->kind())
167           {
168           case Double:
169             CORBA::Double d;
170             *ob >>= d;
171             DEBTRACE( d )
172             break;
173           case Int:
174             CORBA::Long l;
175             *ob >>= l;
176             DEBTRACE( l )
177             break;
178           case String:
179             const char *s;
180             *ob >>= s;
181             DEBTRACE( s )
182             break;
183           case Objref:
184             DEBTRACE( tc->id() )
185             break;
186           default:
187             break;
188           }
189 #endif
190         //OutputPort must copy the input Any(ob). 
191         //This Any will be deleted with the request.
192         //Copy is made by the method put.
193         p->put(ob);
194         out_param=out_param+1;
195 #ifdef REFCNT
196         DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
197 #endif
198       }
199     DEBTRACE( "++++++++++++++++++++++++++++++++++++++++++" )
200   }
201   //Request has been deleted (_var )
202   //All anys given to the request are deleted : don't forget to copy them 
203   //if you want to keep them
204 #ifdef REFCNT
205   list<OutputPort *>::const_iterator iter;
206   for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
207     {
208       OutputCorbaPort *p=(OutputCorbaPort *)*iter;
209       CORBA::Any *ob=p->getAny();
210       DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
211     }
212 #endif
213   DEBTRACE( "+++++++++++++++++ End CorbaNode::execute: " << getName() << " +++++++++++++++++" )
214 }
215
216 //! Clone the node : must also clone the component instance ?
217 Node *CORBANode::simpleClone(ComposedNode *father, bool editionOnly) const
218 {
219   return new CORBANode(*this,father);
220 }
221
222 //! Create a CORBANode with the same component object and no input or output port
223 /*!
224  *   \param name : node name
225  *   \return       a new CORBANode node
226  */
227 ServiceNode* CORBANode::createNode(const std::string& name)
228 {
229
230   CORBANode* node=  new CORBANode(name);
231   node->setComponent(_component);
232   return node;
233 }
234
235 // SalomeNode Class
236
237 const char SalomeNode::KIND[]="Salome";
238
239 std::string SalomeNode::getKind() const
240 {
241   return KIND;
242 }
243
244 //! SalomeNode constructor
245 SalomeNode::SalomeNode(const std::string& name):ServiceNode(name)
246 {
247   _implementation=CORBANode::IMPL_NAME;
248 }
249
250 SalomeNode::SalomeNode(const SalomeNode& other,ComposedNode *father):ServiceNode(other,father)
251 {
252   _implementation=CORBANode::IMPL_NAME;
253 }
254
255 SalomeNode::~SalomeNode()
256 {
257 }
258
259 #ifdef DSC_PORTS
260 //! Init the datastream ports of the component associated to the node
261 void SalomeNode::initService()
262 {
263   DEBTRACE( "SalomeNode::initService: "<<getName())
264   if(_setOfInputDataStreamPort.size() == 0 && _setOfOutputDataStreamPort.size() == 0)return;
265
266   CORBA::Object_var objComponent=((SalomeComponent*)_component)->getCompoPtr();
267   Engines::Superv_Component_var compo=Engines::Superv_Component::_narrow(objComponent);
268   if( CORBA::is_nil(compo) )
269     {
270       throw Exception("Can't get reference to DSC object (or it was nil).");
271     }
272   compo->init_service(_method.c_str());
273 }
274
275 //! Connect the datastream ports of the component associated to the node
276 void SalomeNode::connectService()
277 {
278   DEBTRACE( "SalomeNode::connectService: "<<getName())
279   if(_setOfOutputDataStreamPort.size() == 0)return;
280
281   CORBA::Object_var objComponent=((SalomeComponent*)_component)->getCompoPtr();
282   SALOME_NamingService NS(getSALOMERuntime()->getOrb()) ;
283   SALOME_LifeCycleCORBA LCC(&NS) ;
284   CORBA::Object_var obj = NS.Resolve("/ConnectionManager");
285   Engines::ConnectionManager_var manager=Engines::ConnectionManager::_narrow(obj);
286   Engines::Superv_Component_var me=Engines::Superv_Component::_narrow(objComponent);
287   std::list<OutputDataStreamPort *>::iterator iter;
288   Engines::ConnectionManager::connectionId id;
289   for(iter = _setOfOutputDataStreamPort.begin(); iter != _setOfOutputDataStreamPort.end(); iter++)
290     {
291       OutputDataStreamPort *port=(OutputDataStreamPort *)*iter;
292       std::set<InPort *> ports=port->edSetInPort();
293       std::set<InPort *>::iterator iterout;
294       for(iterout=ports.begin();iterout != ports.end(); iterout++)
295         {
296           //It's only possible to connect 2 SalomeNode : try to get a SalomeNode
297           SalomeNode* snode= dynamic_cast<SalomeNode*>((*iterout)->getNode());
298           if(snode == 0) //don't connect, it's not a SalomeNode
299             throw Exception("Can't connect : not a SalomeNode");
300
301           CORBA::Object_var comp=((SalomeComponent*)snode->getComponent())->getCompoPtr();
302           Engines::Superv_Component_var other=Engines::Superv_Component::_narrow(comp);
303           id=manager->connect(me,port->getName().c_str(),other,(*iterout)->getName().c_str());
304           ids.push_back(id);
305         }
306     }
307
308   //Init component port properties
309   for(iter = _setOfOutputDataStreamPort.begin(); iter != _setOfOutputDataStreamPort.end(); iter++)
310     {
311       (*iter)->initPortProperties();
312     }
313   std::list<InputDataStreamPort *>::iterator iterin;
314   for(iterin = _setOfInputDataStreamPort.begin(); iterin != _setOfInputDataStreamPort.end(); iterin++)
315     {
316       (*iterin)->initPortProperties();
317     }
318 }
319
320 //! Disconnect the datastream ports of the component associated to the node
321 void SalomeNode::disconnectService()
322 {
323   DEBTRACE( "SalomeNode::disconnectService: "<<getName())
324   if(ids.size() == 0)return;
325
326   SALOME_NamingService NS(getSALOMERuntime()->getOrb()) ;
327   SALOME_LifeCycleCORBA LCC(&NS) ;
328   CORBA::Object_var obj = NS.Resolve("/ConnectionManager");
329   Engines::ConnectionManager_var manager=Engines::ConnectionManager::_narrow(obj);
330   std::list<Engines::ConnectionManager::connectionId>::iterator iter;
331   for(iter = ids.begin(); iter != ids.end(); iter++)
332     {
333       manager->disconnect(*iter,Engines::DSC::RemovingConnection);
334     }
335   ids.clear();
336 }
337 #endif
338
339 //! Execute the service on the component associated to the node
340 void SalomeNode::execute()
341 {
342   DEBTRACE( "+++++++++++++++++ SalomeNode::execute: " << getName() << " +++++++++++++++++" )
343   {
344     CORBA::Object_var objComponent=((SalomeComponent*)_component)->getCompoPtr();
345     //DII request building :
346     // a service gets all its in parameters first
347     // then all its out parameters
348     // no inout parameters
349     // the return value (if any) is the first out parameter
350     // not yet user exception (only CORBA exception)
351     //
352     CORBA::Request_var req = objComponent->_request(_method.c_str());
353     CORBA::NVList_ptr arguments = req->arguments() ;
354
355     DEBTRACE( "+++++++++++++++++SalomeNode::inputs+++++++++++++++++" )
356     int in_param=0;
357     //in parameters
358     list<InputPort *>::iterator iter2;
359     for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
360     {
361           InputCorbaPort *p=(InputCorbaPort *)*iter2;
362           DEBTRACE( "port name: " << p->getName() )
363           DEBTRACE( "port kind: " << p->edGetType()->kind() )
364           CORBA::Any* ob=p->getAny();
365 #ifdef _DEVDEBUG_
366           CORBA::TypeCode_var tc;
367           switch(p->edGetType()->kind())
368           {
369           case Double:
370             CORBA::Double d;
371             *ob >>= d;
372             DEBTRACE( d )
373             break;
374           case Int:
375             CORBA::Long l;
376             *ob >>= l;
377             DEBTRACE( l )
378             break;
379           case String:
380             const char *s;
381             *ob >>= s;
382             DEBTRACE( s )
383             break;
384           case Objref:
385             DEBTRACE( tc->id() )
386             break;
387           default:
388             break;
389           }
390 #endif
391           //add_value makes a copy of any. Copy will be deleted with request
392           arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_IN ) ;
393           in_param=in_param+1;
394     }
395     
396     //out parameters
397     DEBTRACE( "+++++++++++++++++SalomeNode::outputs+++++++++++++++++" )
398     list<OutputPort *>::iterator iter;
399     for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
400     {
401           OutputCorbaPort *p=(OutputCorbaPort *)*iter;
402           DEBTRACE( "port name: " << p->getName() )
403           DEBTRACE( "port kind: " << p->edGetType()->kind() )
404           CORBA::Any* ob=p->getAnyOut();
405           //add_value makes a copy of any. Copy will be deleted with request
406           arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_OUT );
407     }
408
409     //return value
410     //if return type is set to void (not mandatory, it's set by default)
411     //the return value will not be marshalled as a return value but 
412     //as the first out argument (don't forget to add it as the first output argument)
413     req->set_return_type(CORBA::_tc_void);
414     //user exceptions
415     //req->exceptions()->add(eo::_tc_SALOME_Exception);
416     
417     DEBTRACE( "+++++++++++++++++SalomeNode::calculation+++++++++++++++++" << _method )
418     req->invoke();
419     CORBA::Exception *exc =req->env()->exception();
420     if( exc )
421     {
422       DEBTRACE( "An exception was thrown!" )
423       DEBTRACE( "The raised exception is of Type:" << exc->_name() )
424       throw Exception("Execution problem");
425     }
426     
427     DEBTRACE( "++++++++++++SalomeNode::outputs++++++++++++" )
428     int out_param=in_param;
429     for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
430     {
431           OutputCorbaPort *p=(OutputCorbaPort *)*iter;
432           DEBTRACE( "port name: " << p->getName() )
433           DEBTRACE( "port kind: " << p->edGetType()->kind() )
434           DEBTRACE( "port number: " << out_param )
435           CORBA::Any *ob=arguments->item(out_param)->value();
436 #ifdef _DEVDEBUG_
437       switch(p->edGetType()->kind())
438       {
439         case Double:
440           CORBA::Double d;
441           *ob >>= d;
442           DEBTRACE( d )
443           break;
444         case Int:
445           CORBA::Long l;
446           *ob >>= l;
447           DEBTRACE( l )
448           break;
449         case String:
450           const char *s;
451           *ob >>= s;
452           DEBTRACE( s )
453           break;
454         default:
455           break;
456       }
457 #endif
458         //OutputPort must copy the input Any(ob). 
459         //This Any will be deleted with the request.
460         //Copy is made by the method put.
461         p->put(ob);
462         out_param=out_param+1;
463     }
464   }
465   //Request has been deleted (_var )
466   //All anys given to the request are deleted : don't forget to copy them 
467   //if you want to keep them
468   DEBTRACE( "+++++++++++++++++ End SalomeNode::execute: " << getName() << " +++++++++++++++++" )
469 }
470
471 Node *SalomeNode::simpleClone(ComposedNode *father, bool editionOnly) const
472 {
473   return new SalomeNode(*this,father);
474 }
475
476 //! Create a SalomeNode with the same component object and no input or output port
477 /*!
478  *   \param name : node name
479  *   \return       a new SalomeNode node
480  */
481 ServiceNode* SalomeNode::createNode(const std::string& name)
482 {
483   SalomeNode* node=new SalomeNode(name);
484   node->setComponent(_component);
485   return node;
486 }