Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[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 #include "TypeCode.hxx"
19
20 #ifdef SALOME_KERNEL
21 #include "SALOME_NamingService.hxx"
22 #include "SALOME_LifeCycleCORBA.hxx"
23 #include "SALOME_Exception.hh"
24 #endif
25
26 #include <omniORB4/CORBA.h>
27 #include <iostream>
28 #include <set>
29 #include <list>
30
31 //#define _DEVDEBUG_
32 #include "YacsTrace.hxx"
33
34 using namespace YACS::ENGINE;
35 using namespace std;
36
37 const char CORBANode::IMPL_NAME[]="CORBA";
38 const char CORBANode::KIND[]="CORBA";
39
40 std::string CORBANode::getKind() const
41 {
42   return KIND;
43 }
44
45 //! CORBANode constructor
46 CORBANode::CORBANode(const std::string& name): ServiceNode(name)
47 {
48   _implementation=IMPL_NAME;
49 }
50
51 CORBANode::CORBANode(const CORBANode& other,ComposedNode *father):ServiceNode(other,father)
52 {
53   _implementation=IMPL_NAME;
54 }
55
56 //! Execute the service on the component associated to the node
57 void CORBANode::execute()
58 {
59   DEBTRACE( "+++++++++++++ CorbaNode::execute: " << getName() << " +++++++++++++++" );
60   {
61     //DII request building :
62     // a service gets all its in parameters first
63     // then all its out parameters
64     // no inout parameters
65     // the return value (if any) is the first out parameter
66     // not yet user exception (only CORBA exception)
67
68     CORBA::Object_var objComponent=((CORBAComponent*)_component)->getCompoPtr();
69     CORBA::Request_var req = objComponent->_request(_method.c_str());
70     CORBA::NVList_ptr arguments = req->arguments() ;
71
72     DEBTRACE( "+++++++++++++++++CorbaNode::inputs+++++++++++++++++" )
73     int in_param=0;
74     //in parameters
75     list<InputPort *>::iterator iter2;
76     for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
77       {
78         InputCorbaPort *p=(InputCorbaPort *)*iter2;
79         DEBTRACE( "port name: " << p->getName() )
80         DEBTRACE( "port kind: " << p->edGetType()->kind() )
81         CORBA::Any* ob=p->getAny();
82 #ifdef _DEVDEBUG_
83         CORBA::TypeCode_var typcod= ob->type();
84         switch(p->edGetType()->kind())
85           {
86           case Double:
87             CORBA::Double d;
88             *ob >>= d;
89             DEBTRACE( d )
90             break;
91           case Int:
92             CORBA::Long l;
93             *ob >>= l;
94             DEBTRACE( l )
95             break;
96           case String:
97             const char *s;
98             *ob >>= s;
99             DEBTRACE( s )
100             break;
101           case Bool:
102             CORBA::Boolean b;
103             if(*ob >>= CORBA::Any::to_boolean(b))
104               DEBTRACE( b )
105             else 
106               DEBTRACE( "not a boolean" )
107             break;
108           case Objref:
109             DEBTRACE( typcod->id() )
110             break;
111           default:
112             break;
113           }
114 #endif
115         //add_value makes a copy of any (*ob). This copy will be deleted with the request
116         arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_IN ) ;
117         in_param=in_param+1;
118       }
119     
120     //output parameters
121     DEBTRACE( "+++++++++++++++++CorbaNode::outputs+++++++++++++++++" )
122     list<OutputPort *>::iterator iter;
123     for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
124       {
125         OutputCorbaPort *p=(OutputCorbaPort *)*iter;
126         DEBTRACE( "port name: " << p->getName() )
127         DEBTRACE( "port kind: " << p->edGetType()->kind() )
128         CORBA::Any* ob=p->getAnyOut();
129 #ifdef REFCNT
130         DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
131 #endif
132         //add_value makes a copy of any. Copy will be deleted with request
133         arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_OUT );
134 #ifdef REFCNT
135         DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
136 #endif
137         delete ob;
138       }
139
140     //return value
141     req->set_return_type(CORBA::_tc_void);
142     
143     DEBTRACE( "+++++++++++++++++CorbaNode::calculation+++++++++++++++++" << _method )
144     req->invoke();
145     CORBA::Exception *exc =req->env()->exception();
146     if( exc )
147       {
148         DEBTRACE( "An exception was thrown!" )
149         DEBTRACE( "The raised exception is of Type:" << exc->_name() )
150
151         std::cerr << "The raised exception is of Type:" << exc->_name() << std::endl;
152         /*
153         if(strcmp(exc->_name(),"MARSHAL") == 0)
154           {
155             const char* ms = ((CORBA::MARSHAL*)exc)->NP_minorString();
156             if (ms)
157                std::cerr << "(CORBA::MARSHAL: minor = " << ms << ")" << std::endl;
158             else
159                std::cerr << "(CORBA::MARSHAL: minor = " << ((CORBA::MARSHAL*)exc)->minor() << ")" << std::endl;
160           }
161           */
162         _errorDetails="Execution problem: the raised exception is of Type:";
163         _errorDetails += exc->_name();
164         throw Exception("Execution problem");
165       }
166     
167     DEBTRACE( "++++++++++++CorbaNode::outputs++++++++++++" )
168     int out_param=in_param;
169     for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
170       {
171         OutputCorbaPort *p=(OutputCorbaPort *)*iter;
172         DEBTRACE( "port name: " << p->getName() )
173         DEBTRACE( "port kind: " << p->edGetType()->kind() )
174         DEBTRACE( "port number: " << out_param )
175         CORBA::Any *ob=arguments->item(out_param)->value();
176 #ifdef REFCNT
177         DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
178 #endif
179 #ifdef _DEVDEBUG_
180         CORBA::TypeCode_var tc=ob->type();
181         switch(p->edGetType()->kind())
182           {
183           case Double:
184             CORBA::Double d;
185             *ob >>= d;
186             DEBTRACE( d )
187             break;
188           case Int:
189             CORBA::Long l;
190             *ob >>= l;
191             DEBTRACE( l )
192             break;
193           case String:
194             const char *s;
195             *ob >>= s;
196             DEBTRACE( s )
197             break;
198           case Objref:
199             DEBTRACE( tc->id() )
200             break;
201           default:
202             break;
203           }
204 #endif
205         //OutputPort must copy the input Any(ob). 
206         //This Any will be deleted with the request.
207         //Copy is made by the method put.
208         p->put(ob);
209         out_param=out_param+1;
210 #ifdef REFCNT
211         DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
212 #endif
213       }
214     DEBTRACE( "++++++++++++++++++++++++++++++++++++++++++" )
215   }
216   //Request has been deleted (_var )
217   //All anys given to the request are deleted : don't forget to copy them 
218   //if you want to keep them
219 #ifdef REFCNT
220   list<OutputPort *>::const_iterator iter;
221   for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
222     {
223       OutputCorbaPort *p=(OutputCorbaPort *)*iter;
224       CORBA::Any *ob=p->getAny();
225       DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
226     }
227 #endif
228   DEBTRACE( "+++++++++++++++++ End CorbaNode::execute: " << getName() << " +++++++++++++++++" )
229 }
230
231 //! Clone the node : must also clone the component instance ?
232 Node *CORBANode::simpleClone(ComposedNode *father, bool editionOnly) const
233 {
234   return new CORBANode(*this,father);
235 }
236
237 //! Create a CORBANode with the same component object and no input or output port
238 /*!
239  *   \param name : node name
240  *   \return       a new CORBANode node
241  */
242 ServiceNode* CORBANode::createNode(const std::string& name)
243 {
244
245   CORBANode* node=  new CORBANode(name);
246   node->setComponent(_component);
247   return node;
248 }
249
250 // SalomeNode Class
251
252 const char SalomeNode::KIND[]="Salome";
253
254 std::string SalomeNode::getKind() const
255 {
256   return KIND;
257 }
258
259 //! SalomeNode constructor
260 SalomeNode::SalomeNode(const std::string& name):ServiceNode(name)
261 {
262   _implementation=CORBANode::IMPL_NAME;
263 }
264
265 SalomeNode::SalomeNode(const SalomeNode& other,ComposedNode *father):ServiceNode(other,father)
266 {
267   _implementation=CORBANode::IMPL_NAME;
268 }
269
270 SalomeNode::~SalomeNode()
271 {
272 }
273
274 #ifdef DSC_PORTS
275 //! Init the datastream ports of the component associated to the node
276 void SalomeNode::initService()
277 {
278   DEBTRACE( "SalomeNode::initService: "<<getName())
279   if(_setOfInputDataStreamPort.size() == 0 && _setOfOutputDataStreamPort.size() == 0)return;
280
281   CORBA::Object_var objComponent=((SalomeComponent*)_component)->getCompoPtr();
282   Engines::Superv_Component_var compo=Engines::Superv_Component::_narrow(objComponent);
283   if( CORBA::is_nil(compo) )
284     {
285       std::string msg="Can't get reference to DSC object (or it was nil).";
286       _errorDetails=msg;
287       throw Exception(msg);
288     }
289   try
290     {
291       CORBA::Boolean ret=compo->init_service(_method.c_str());
292       if(!ret)
293         {
294           _errorDetails="Problem with component '"+_ref+"' in init_service of service '"+ _method + "'";
295           throw Exception(_errorDetails);
296         }
297     }
298   catch(...)
299     {
300       _errorDetails="Problem with component '"+_ref+"' in init_service of service '"+ _method + "'";
301       throw;
302     }
303 }
304
305 //! Connect the datastream ports of the component associated to the node
306 void SalomeNode::connectService()
307 {
308   DEBTRACE( "SalomeNode::connectService: "<<getName());
309   if(_setOfOutputDataStreamPort.size() == 0)return;
310
311   CORBA::Object_var objComponent=((SalomeComponent*)_component)->getCompoPtr();
312   SALOME_NamingService NS(getSALOMERuntime()->getOrb()) ;
313   SALOME_LifeCycleCORBA LCC(&NS) ;
314   CORBA::Object_var obj = NS.Resolve("/ConnectionManager");
315   Engines::ConnectionManager_var manager=Engines::ConnectionManager::_narrow(obj);
316   Engines::Superv_Component_var me=Engines::Superv_Component::_narrow(objComponent);
317   if( CORBA::is_nil(me) )
318     {
319       std::string msg="Can't get reference to Engines::Superv_Component: "+getName();
320       _errorDetails=msg;
321       throw Exception(msg);
322     }
323   std::list<OutputDataStreamPort *>::iterator iter;
324   Engines::ConnectionManager::connectionId id;
325   for(iter = _setOfOutputDataStreamPort.begin(); iter != _setOfOutputDataStreamPort.end(); iter++)
326     {
327       OutputDataStreamPort *port=(OutputDataStreamPort *)*iter;
328       std::set<InPort *> ports=port->edSetInPort();
329       std::set<InPort *>::iterator iterout;
330       for(iterout=ports.begin();iterout != ports.end(); iterout++)
331         {
332           //It's only possible to connect 2 SalomeNode : try to get a SalomeNode
333           SalomeNode* snode= dynamic_cast<SalomeNode*>((*iterout)->getNode());
334           if(snode == 0) //don't connect, it's not a SalomeNode
335             {
336               std::string msg="Can't connect : not a SalomeNode";
337               _errorDetails=msg;
338               throw Exception(msg);
339             }
340
341           CORBA::Object_var comp=((SalomeComponent*)snode->getComponent())->getCompoPtr();
342           if( CORBA::is_nil(comp))
343             {
344               std::string msg="Problem in connectService: " + snode->getName();
345               msg=msg+" Component is probably not launched. Modify your YACS file";
346               _errorDetails=msg;
347               throw Exception(msg);
348             }
349
350           Engines::Superv_Component_var other=Engines::Superv_Component::_narrow(comp);
351           if( CORBA::is_nil(other))
352             {
353               std::string msg="Can't connect to nil Engines::Superv_Component: " + snode->getName();
354               _errorDetails=msg;
355               throw Exception(msg);
356             }
357           try
358             {
359               id=manager->connect(me,port->getName().c_str(),other,(*iterout)->getName().c_str());
360             }
361           catch(Engines::DSC::PortNotDefined& ex)
362             {
363               std::string msg="Problem in connectService. Unknown port: "+port->getName()+" or "+(*iterout)->getName();
364               _errorDetails=msg;
365               throw Exception(msg);
366             }
367           catch(Engines::DSC::BadPortType& ex)
368             {
369               std::string msg="Problem in connectService. Type of provides port is bad. Expected: ";
370               msg=msg + ex.expected.in();
371               msg=msg + "Received: "+ex.received.in();
372               _errorDetails=msg;
373               throw Exception(msg);
374             }
375           catch(Engines::DSC::NilPort& ex)
376             {
377               std::string msg="Problem in connectService. Port is nil: "+port->getName()+" or "+(*iterout)->getName();
378               _errorDetails=msg;
379               throw Exception(msg);
380             }
381           catch( const SALOME::SALOME_Exception& ex )
382             {
383               std::string msg="Problem in connectService. ";
384               msg += ex.details.text.in();
385               msg=msg+getName()+" " + port->getName() + " " + snode->getName() + " " + (*iterout)->getName();
386               _errorDetails=msg;
387               throw Exception(msg);
388             }
389           catch(CORBA::SystemException& ex)
390             {
391               std::string msg="Problem in connectService. CORBA System exception";
392               msg=msg+getName()+" " + port->getName() + " " + snode->getName() + " " + (*iterout)->getName();
393               throw Exception(msg);
394             }
395           catch(...)
396             {
397               std::string msg="Problem in connectService. Unknown exception";
398               msg=msg+getName()+" " + port->getName() + " " + snode->getName() + " " + (*iterout)->getName();
399               throw Exception(msg);
400             }
401           DEBTRACE("Connected: " <<id<<" "<<getName()<<" "<<port->getName()<<" "<<snode->getName()<<" "<<(*iterout)->getName());
402           ids.push_back(id);
403         }
404     }
405
406   //Init component port properties
407   for(iter = _setOfOutputDataStreamPort.begin(); iter != _setOfOutputDataStreamPort.end(); iter++)
408     {
409       (*iter)->initPortProperties();
410     }
411   std::list<InputDataStreamPort *>::iterator iterin;
412   for(iterin = _setOfInputDataStreamPort.begin(); iterin != _setOfInputDataStreamPort.end(); iterin++)
413     {
414       (*iterin)->initPortProperties();
415     }
416 }
417
418 //! Disconnect the datastream ports of the component associated to the node
419 void SalomeNode::disconnectService()
420 {
421   DEBTRACE( "SalomeNode::disconnectService: "<<getName());
422   if(ids.size() == 0)return;
423
424   SALOME_NamingService NS(getSALOMERuntime()->getOrb()) ;
425   SALOME_LifeCycleCORBA LCC(&NS) ;
426   CORBA::Object_var obj = NS.Resolve("/ConnectionManager");
427   Engines::ConnectionManager_var manager=Engines::ConnectionManager::_narrow(obj);
428   std::list<Engines::ConnectionManager::connectionId>::iterator iter;
429   for(iter = ids.begin(); iter != ids.end(); iter++)
430     {
431       DEBTRACE("Trying to disconnect: " << *iter );
432       try
433         {
434           manager->disconnect(*iter,Engines::DSC::RemovingConnection);
435         }
436       catch(Engines::ConnectionManager::BadId& ex)
437         {
438           DEBTRACE( "Problem in disconnect: " << *iter );
439         }
440       catch(Engines::DSC::PortNotDefined& ex)
441         {
442           DEBTRACE( "Problem in disconnect: " << *iter );
443         }
444       catch(Engines::DSC::PortNotConnected& ex)
445         {
446           DEBTRACE( "Problem in disconnect: " << *iter );
447         }
448       catch(Engines::DSC::BadPortReference& ex)
449         {
450           DEBTRACE( "Problem in disconnect (Engines::DSC::BadPortReference): " << *iter );
451         }
452       catch(CORBA::SystemException& ex)
453         {
454           DEBTRACE( "Problem in disconnect (CORBA::SystemException): " << *iter );
455         }
456       catch(...)
457         {
458           DEBTRACE( "Problem in disconnect: " << *iter );
459         }
460     }
461   ids.clear();
462 }
463 #endif
464
465 //! Execute the service on the component associated to the node
466 void SalomeNode::execute()
467 {
468   DEBTRACE( "+++++++++++++++++ SalomeNode::execute: " << getName() << " " << _method << " +++++++++++++++++" )
469   {
470     CORBA::Object_var objComponent=((SalomeComponent*)_component)->getCompoPtr();
471     Engines::Component_var compo=Engines::Component::_narrow(objComponent);
472
473     // Set component properties
474     if(_propertyMap.size() > 0)
475       {
476         Engines::FieldsDict_var dico = new Engines::FieldsDict;
477         dico->length(_propertyMap.size());
478         std::map<std::string,std::string>::const_iterator it;
479         int i=0;
480         for(it = _propertyMap.begin(); it != _propertyMap.end(); ++it)
481           {
482             dico[i].key=CORBA::string_dup(it->first.c_str());
483             dico[i].value <<=it->second.c_str();
484             i++;
485           }
486         compo->setProperties(dico);
487       }
488
489     //DII request building :
490     // a service gets all its in parameters first
491     // then all its out parameters
492     // no inout parameters
493     // the return value (if any) is the first out parameter
494     //
495     CORBA::Request_var req ;
496     try
497       {
498         req = objComponent->_request(_method.c_str());
499       }
500     catch(CORBA::SystemException& ex)
501       {
502         std::string msg="component '" +_ref+ "' has no service '" + _method+ "'";
503         _errorDetails=msg;
504         throw Exception(msg);
505       }
506     CORBA::NVList_ptr arguments = req->arguments() ;
507
508     DEBTRACE( "+++++++++++++++++SalomeNode::inputs+++++++++++++++++" );
509     int in_param=0;
510     //in parameters
511     list<InputPort *>::iterator iter2;
512     for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
513     {
514           InputCorbaPort *p=(InputCorbaPort *)*iter2;
515           if(p->edGetType()->isA(Runtime::_tc_file))
516             continue;
517           DEBTRACE( "port name: " << p->getName() );
518           DEBTRACE( "port kind: " << p->edGetType()->kind() );
519           CORBA::Any* ob=p->getAny();
520 #ifdef _DEVDEBUG_
521           CORBA::TypeCode_var tc=ob->type();
522           switch(p->edGetType()->kind())
523           {
524           case Double:
525             CORBA::Double d;
526             *ob >>= d;
527             DEBTRACE( d )
528             break;
529           case Int:
530             CORBA::Long l;
531             *ob >>= l;
532             DEBTRACE( l )
533             break;
534           case String:
535             const char *s;
536             *ob >>= s;
537             DEBTRACE( s )
538             break;
539           case Objref:
540             DEBTRACE( tc->id() )
541             break;
542           default:
543             break;
544           }
545 #endif
546           //add_value makes a copy of any. Copy will be deleted with request
547           arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_IN ) ;
548           in_param=in_param+1;
549     }
550     //in files
551     int nfiles=0;
552     DEBTRACE("checkInputFilesToService: " << _method);
553     try
554       {
555         for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
556           {
557             InputCorbaPort *p=(InputCorbaPort *)*iter2;
558             if(!p->edGetType()->isA(Runtime::_tc_file))
559               continue;
560             std::string filename=p->getName();
561             // replace ':' by '.'. Needed because port name can not contain '.'
562             string::size_type debut =filename.find_first_of(':',0);
563             while(debut != std::string::npos)
564               {
565                  filename[debut]='.';
566                  debut=filename.find_first_of(':',debut);
567               }
568             DEBTRACE( "inport with file: " << filename );
569             Engines::Salome_file_var isf=compo->setInputFileToService(_method.c_str(),p->getName().c_str());
570             isf->setDistributedFile(filename.c_str());
571             Engines::Salome_file_ptr osf;
572             CORBA::Any* any=p->getAny();
573             *any >>= osf;
574             isf->connect(osf);
575             nfiles++;
576           }
577         if(nfiles)
578           compo->checkInputFilesToService(_method.c_str());
579       }
580     catch( const SALOME::SALOME_Exception& ex )
581       {
582         std::string text="Execution problem in checkInputFilesToService: ";
583         text += (const char*)ex.details.text;
584         _errorDetails=text;
585         throw Exception(text);
586       }
587     catch(CORBA::SystemException& ex)
588       {
589         std::string msg="Execution problem: component probably does not support files ??";
590         _errorDetails=msg;
591         throw Exception(msg);
592       }
593     
594     //out parameters
595     DEBTRACE( "+++++++++++++++++SalomeNode::outputs+++++++++++++++++" )
596     list<OutputPort *>::iterator iter;
597     for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
598     {
599           OutputCorbaPort *p=(OutputCorbaPort *)*iter;
600           DEBTRACE( "port name: " << p->getName() )
601           DEBTRACE( "port kind: " << p->edGetType()->kind() )
602           if(p->edGetType()->isA(Runtime::_tc_file))
603             continue;
604           CORBA::Any* ob=p->getAnyOut();
605           //add_value makes a copy of any. Copy will be deleted with request
606           arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_OUT );
607           delete ob;
608     }
609
610     //return value
611     //if return type is set to void (not mandatory, it's set by default)
612     //the return value will not be marshalled as a return value but 
613     //as the first out argument (don't forget to add it as the first output argument)
614     req->set_return_type(CORBA::_tc_void);
615     //user exceptions
616     req->exceptions()->add(SALOME::_tc_SALOME_Exception);
617     
618     DEBTRACE( "+++++++++++++++++SalomeNode::calculation+++++++++++++++++" << _method )
619     req->invoke();
620     CORBA::Exception *exc =req->env()->exception();
621     if( exc )
622     {
623       DEBTRACE( "An exception was thrown!" )
624       DEBTRACE( "The raised exception is of Type:" << exc->_name() )
625
626       CORBA::SystemException* sysexc;
627       sysexc=CORBA::SystemException::_downcast(exc);
628       if(sysexc != NULL)
629         {
630           // It's a SystemException
631           DEBTRACE( "minor code: " << sysexc->minor() );
632           DEBTRACE( "completion code: " << sysexc->completed() );
633           std::string text="Execution problem: ";
634           std::string excname=sysexc->_name();
635           if(excname == "BAD_OPERATION")
636             {
637               text=text+"component '" +_ref+ "' has no service '" + _method+ "'";
638             }
639           else
640             {
641               text=text+"System Exception "+ excname;
642             }
643           _errorDetails=text;
644           throw Exception(text);
645         }
646
647       // Not a System Exception
648       CORBA::UnknownUserException* userexc;
649       userexc=CORBA::UnknownUserException::_downcast(exc);
650       if(userexc != NULL)
651         {
652           CORBA::Any anyExcept = userexc->exception(); 
653
654           const SALOME::SALOME_Exception* salexc;
655           if(anyExcept >>= salexc)
656             {
657               DEBTRACE("SALOME_Exception: "<< salexc->details.sourceFile);
658               DEBTRACE("SALOME_Exception: "<<salexc->details.lineNumber);
659               _errorDetails=salexc->details.text;
660               throw Exception("Execution problem: Salome Exception occurred" + getErrorDetails() );
661             }
662           std::string msg="Execution problem: User Exception occurred";
663           _errorDetails=msg;
664           throw Exception(msg);
665         }
666       std::string msg="Execution problem";
667       _errorDetails=msg;
668       throw Exception(msg);
669     }
670     
671     DEBTRACE( "++++++++++++SalomeNode::outputs++++++++++++" )
672     int out_param=in_param;
673     for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
674     {
675           OutputCorbaPort *p=(OutputCorbaPort *)*iter;
676           DEBTRACE( "port name: " << p->getName() );
677           DEBTRACE( "port kind: " << p->edGetType()->kind() );
678           DEBTRACE( "port number: " << out_param );
679           if(p->edGetType()->isA(Runtime::_tc_file))
680             continue;
681           CORBA::Any *ob=arguments->item(out_param)->value();
682 #ifdef _DEVDEBUG_
683       switch(p->edGetType()->kind())
684       {
685         case Double:
686           CORBA::Double d;
687           *ob >>= d;
688           DEBTRACE( d )
689           break;
690         case Int:
691           CORBA::Long l;
692           *ob >>= l;
693           DEBTRACE( l )
694           break;
695         case String:
696           const char *s;
697           *ob >>= s;
698           DEBTRACE( s )
699           break;
700         default:
701           break;
702       }
703 #endif
704         //OutputPort must copy the input Any(ob). 
705         //This Any will be deleted with the request.
706         //Copy is made by the method put.
707         p->put(ob);
708         out_param=out_param+1;
709     }
710
711     //Out files
712     nfiles=0;
713     DEBTRACE("checkOutputFilesToService: " << _method);
714     try
715       {
716         for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
717           {
718             OutputCorbaPort *p=(OutputCorbaPort *)*iter;
719             if(!p->edGetType()->isA(Runtime::_tc_file))
720               continue;
721             // The output port has a file object : special treatment
722             std::string filename=p->getName();
723             // replace ':' by '.'. Needed because port name can not contain '.'
724             string::size_type debut =filename.find_first_of(':',0);
725             while(debut != std::string::npos)
726               {
727                  filename[debut]='.';
728                  debut=filename.find_first_of(':',debut);
729               }
730             DEBTRACE( "outport with file: " << filename );
731             Engines::Salome_file_var osf=compo->setOutputFileToService(_method.c_str(),p->getName().c_str());
732             osf->setLocalFile(filename.c_str());
733             CORBA::Any any;
734             any <<= osf;
735             p->put(&any);
736           }
737         if(nfiles)
738           compo->checkOutputFilesToService(_method.c_str());
739       }
740     catch( const SALOME::SALOME_Exception& ex )
741       {
742         std::string text=(const char*)ex.details.text;
743         _errorDetails=text;
744         throw Exception("Execution problem in checkOutputFilesToService: " + text);
745       }
746     catch(CORBA::SystemException& ex)
747       {
748         std::string msg="Execution problem: component probably does not support files ?";
749         _errorDetails=msg;
750         throw Exception(msg);
751       }
752   }
753   //Request has been deleted (_var )
754   //All anys given to the request are deleted : don't forget to copy them 
755   //if you want to keep them
756   DEBTRACE( "+++++++++++++++++ End SalomeNode::execute: " << getName() << " +++++++++++++++++" )
757 }
758
759 Node *SalomeNode::simpleClone(ComposedNode *father, bool editionOnly) const
760 {
761   return new SalomeNode(*this,father);
762 }
763
764 //! Create a SalomeNode with the same component object and no input or output port
765 /*!
766  *   \param name : node name
767  *   \return       a new SalomeNode node
768  */
769 ServiceNode* SalomeNode::createNode(const std::string& name)
770 {
771   SalomeNode* node=new SalomeNode(name);
772   node->setComponent(_component);
773   return node;
774 }
775
776 std::string SalomeNode::getContainerLog()
777 {
778   std::string msg="Component is not loaded";
779   CORBA::Object_var objComponent=((SalomeComponent*)_component)->getCompoPtr();
780   Engines::Component_var compo=Engines::Component::_narrow(objComponent);
781   if( !CORBA::is_nil(compo) )
782     {
783       Engines::Container_var cont= compo->GetContainerRef();
784       CORBA::String_var logname = cont->logfilename();
785       DEBTRACE(logname);
786       msg=logname;
787       std::string::size_type pos = msg.find(":");
788       msg=msg.substr(pos+1);
789     }
790   return msg;
791 }