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