5 #define protected public
6 #include <omniORB4/CORBA.h>
7 #include <omniORB4/internal/typecode.h>
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"
18 #include "TypeCode.hxx"
21 #include "SALOME_NamingService.hxx"
22 #include "SALOME_LifeCycleCORBA.hxx"
23 #include "SALOME_Exception.hh"
26 #include <omniORB4/CORBA.h>
32 #include "YacsTrace.hxx"
34 using namespace YACS::ENGINE;
37 const char CORBANode::IMPL_NAME[]="CORBA";
38 const char CORBANode::KIND[]="CORBA";
40 std::string CORBANode::getKind() const
45 //! CORBANode constructor
46 CORBANode::CORBANode(const std::string& name): ServiceNode(name)
48 _implementation=IMPL_NAME;
51 CORBANode::CORBANode(const CORBANode& other,ComposedNode *father):ServiceNode(other,father)
53 _implementation=IMPL_NAME;
56 //! Execute the service on the component associated to the node
57 void CORBANode::execute()
59 DEBTRACE( "+++++++++++++ CorbaNode::execute: " << getName() << " +++++++++++++++" );
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)
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() ;
72 DEBTRACE( "+++++++++++++++++CorbaNode::inputs+++++++++++++++++" )
75 list<InputPort *>::iterator iter2;
76 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
78 InputCorbaPort *p=(InputCorbaPort *)*iter2;
79 DEBTRACE( "port name: " << p->getName() )
80 DEBTRACE( "port kind: " << p->edGetType()->kind() )
81 CORBA::Any* ob=p->getAny();
83 CORBA::TypeCode_var typcod= ob->type();
84 switch(p->edGetType()->kind())
103 if(*ob >>= CORBA::Any::to_boolean(b))
106 DEBTRACE( "not a boolean" )
109 DEBTRACE( typcod->id() )
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 ) ;
121 DEBTRACE( "+++++++++++++++++CorbaNode::outputs+++++++++++++++++" )
122 list<OutputPort *>::iterator iter;
123 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
125 OutputCorbaPort *p=(OutputCorbaPort *)*iter;
126 DEBTRACE( "port name: " << p->getName() )
127 DEBTRACE( "port kind: " << p->edGetType()->kind() )
128 CORBA::Any* ob=p->getAnyOut();
130 DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
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 );
135 DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
141 req->set_return_type(CORBA::_tc_void);
143 DEBTRACE( "+++++++++++++++++CorbaNode::calculation+++++++++++++++++" << _method )
145 CORBA::Exception *exc =req->env()->exception();
148 DEBTRACE( "An exception was thrown!" )
149 DEBTRACE( "The raised exception is of Type:" << exc->_name() )
151 std::cerr << "The raised exception is of Type:" << exc->_name() << std::endl;
153 if(strcmp(exc->_name(),"MARSHAL") == 0)
155 const char* ms = ((CORBA::MARSHAL*)exc)->NP_minorString();
157 std::cerr << "(CORBA::MARSHAL: minor = " << ms << ")" << std::endl;
159 std::cerr << "(CORBA::MARSHAL: minor = " << ((CORBA::MARSHAL*)exc)->minor() << ")" << std::endl;
162 _errorDetails="Execution problem: the raised exception is of Type:";
163 _errorDetails += exc->_name();
164 throw Exception("Execution problem");
167 DEBTRACE( "++++++++++++CorbaNode::outputs++++++++++++" )
168 int out_param=in_param;
169 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
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();
177 DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
180 CORBA::TypeCode_var tc=ob->type();
181 switch(p->edGetType()->kind())
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.
209 out_param=out_param+1;
211 DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count);
214 DEBTRACE( "++++++++++++++++++++++++++++++++++++++++++" )
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
220 list<OutputPort *>::const_iterator iter;
221 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
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);
228 DEBTRACE( "+++++++++++++++++ End CorbaNode::execute: " << getName() << " +++++++++++++++++" )
231 //! Clone the node : must also clone the component instance ?
232 Node *CORBANode::simpleClone(ComposedNode *father, bool editionOnly) const
234 return new CORBANode(*this,father);
237 //! Create a CORBANode with the same component object and no input or output port
239 * \param name : node name
240 * \return a new CORBANode node
242 ServiceNode* CORBANode::createNode(const std::string& name)
245 CORBANode* node= new CORBANode(name);
246 node->setComponent(_component);
252 const char SalomeNode::KIND[]="Salome";
254 std::string SalomeNode::getKind() const
259 //! SalomeNode constructor
260 SalomeNode::SalomeNode(const std::string& name):ServiceNode(name)
262 _implementation=CORBANode::IMPL_NAME;
265 SalomeNode::SalomeNode(const SalomeNode& other,ComposedNode *father):ServiceNode(other,father)
267 _implementation=CORBANode::IMPL_NAME;
270 SalomeNode::~SalomeNode()
275 //! Init the datastream ports of the component associated to the node
276 void SalomeNode::initService()
278 DEBTRACE( "SalomeNode::initService: "<<getName())
279 if(_setOfInputDataStreamPort.size() == 0 && _setOfOutputDataStreamPort.size() == 0)return;
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) )
285 std::string msg="Can't get reference to DSC object (or it was nil).";
287 throw Exception(msg);
291 CORBA::Boolean ret=compo->init_service(_method.c_str());
294 _errorDetails="Problem with component '"+_ref+"' in init_service of service '"+ _method + "'";
295 throw Exception(_errorDetails);
300 _errorDetails="Problem with component '"+_ref+"' in init_service of service '"+ _method + "'";
305 //! Connect the datastream ports of the component associated to the node
306 void SalomeNode::connectService()
308 DEBTRACE( "SalomeNode::connectService: "<<getName());
309 if(_setOfOutputDataStreamPort.size() == 0)return;
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) )
319 std::string msg="Can't get reference to Engines::Superv_Component: "+getName();
321 throw Exception(msg);
323 std::list<OutputDataStreamPort *>::iterator iter;
324 Engines::ConnectionManager::connectionId id;
325 for(iter = _setOfOutputDataStreamPort.begin(); iter != _setOfOutputDataStreamPort.end(); iter++)
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++)
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
336 std::string msg="Can't connect : not a SalomeNode";
338 throw Exception(msg);
341 CORBA::Object_var comp=((SalomeComponent*)snode->getComponent())->getCompoPtr();
342 if( CORBA::is_nil(comp))
344 std::string msg="Problem in connectService: " + snode->getName();
345 msg=msg+" Component is probably not launched. Modify your YACS file";
347 throw Exception(msg);
350 Engines::Superv_Component_var other=Engines::Superv_Component::_narrow(comp);
351 if( CORBA::is_nil(other))
353 std::string msg="Can't connect to nil Engines::Superv_Component: " + snode->getName();
355 throw Exception(msg);
359 id=manager->connect(me,port->getName().c_str(),other,(*iterout)->getName().c_str());
361 catch(Engines::DSC::PortNotDefined& ex)
363 std::string msg="Problem in connectService. Unknown port: "+port->getName()+" or "+(*iterout)->getName();
365 throw Exception(msg);
367 catch(Engines::DSC::BadPortType& ex)
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();
373 throw Exception(msg);
375 catch(Engines::DSC::NilPort& ex)
377 std::string msg="Problem in connectService. Port is nil: "+port->getName()+" or "+(*iterout)->getName();
379 throw Exception(msg);
381 catch( const SALOME::SALOME_Exception& ex )
383 std::string msg="Problem in connectService. ";
384 msg += ex.details.text.in();
385 msg=msg+getName()+" " + port->getName() + " " + snode->getName() + " " + (*iterout)->getName();
387 throw Exception(msg);
389 catch(CORBA::SystemException& ex)
391 std::string msg="Problem in connectService. CORBA System exception";
392 msg=msg+getName()+" " + port->getName() + " " + snode->getName() + " " + (*iterout)->getName();
393 throw Exception(msg);
397 std::string msg="Problem in connectService. Unknown exception";
398 msg=msg+getName()+" " + port->getName() + " " + snode->getName() + " " + (*iterout)->getName();
399 throw Exception(msg);
401 DEBTRACE("Connected: " <<id<<" "<<getName()<<" "<<port->getName()<<" "<<snode->getName()<<" "<<(*iterout)->getName());
406 //Init component port properties
407 for(iter = _setOfOutputDataStreamPort.begin(); iter != _setOfOutputDataStreamPort.end(); iter++)
409 (*iter)->initPortProperties();
411 std::list<InputDataStreamPort *>::iterator iterin;
412 for(iterin = _setOfInputDataStreamPort.begin(); iterin != _setOfInputDataStreamPort.end(); iterin++)
414 (*iterin)->initPortProperties();
418 //! Disconnect the datastream ports of the component associated to the node
419 void SalomeNode::disconnectService()
421 DEBTRACE( "SalomeNode::disconnectService: "<<getName());
422 if(ids.size() == 0)return;
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++)
431 DEBTRACE("Trying to disconnect: " << *iter );
434 manager->disconnect(*iter,Engines::DSC::RemovingConnection);
436 catch(Engines::ConnectionManager::BadId& ex)
438 DEBTRACE( "Problem in disconnect: " << *iter );
440 catch(Engines::DSC::PortNotDefined& ex)
442 DEBTRACE( "Problem in disconnect: " << *iter );
444 catch(Engines::DSC::PortNotConnected& ex)
446 DEBTRACE( "Problem in disconnect: " << *iter );
448 catch(Engines::DSC::BadPortReference& ex)
450 DEBTRACE( "Problem in disconnect (Engines::DSC::BadPortReference): " << *iter );
452 catch(CORBA::SystemException& ex)
454 DEBTRACE( "Problem in disconnect (CORBA::SystemException): " << *iter );
458 DEBTRACE( "Problem in disconnect: " << *iter );
465 //! Execute the service on the component associated to the node
466 void SalomeNode::execute()
468 DEBTRACE( "+++++++++++++++++ SalomeNode::execute: " << getName() << " " << _method << " +++++++++++++++++" )
470 CORBA::Object_var objComponent=((SalomeComponent*)_component)->getCompoPtr();
471 Engines::Component_var compo=Engines::Component::_narrow(objComponent);
473 // Set component properties
474 if(_propertyMap.size() > 0)
476 Engines::FieldsDict_var dico = new Engines::FieldsDict;
477 dico->length(_propertyMap.size());
478 std::map<std::string,std::string>::const_iterator it;
480 for(it = _propertyMap.begin(); it != _propertyMap.end(); ++it)
482 dico[i].key=CORBA::string_dup(it->first.c_str());
483 dico[i].value <<=it->second.c_str();
486 compo->setProperties(dico);
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
495 CORBA::Request_var req ;
498 req = objComponent->_request(_method.c_str());
500 catch(CORBA::SystemException& ex)
502 std::string msg="component '" +_ref+ "' has no service '" + _method+ "'";
504 throw Exception(msg);
506 CORBA::NVList_ptr arguments = req->arguments() ;
508 DEBTRACE( "+++++++++++++++++SalomeNode::inputs+++++++++++++++++" );
511 list<InputPort *>::iterator iter2;
512 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
514 InputCorbaPort *p=(InputCorbaPort *)*iter2;
515 if(p->edGetType()->isA(Runtime::_tc_file))
517 DEBTRACE( "port name: " << p->getName() );
518 DEBTRACE( "port kind: " << p->edGetType()->kind() );
519 CORBA::Any* ob=p->getAny();
521 CORBA::TypeCode_var tc=ob->type();
522 switch(p->edGetType()->kind())
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 ) ;
552 DEBTRACE("checkInputFilesToService: " << _method);
555 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
557 InputCorbaPort *p=(InputCorbaPort *)*iter2;
558 if(!p->edGetType()->isA(Runtime::_tc_file))
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)
566 debut=filename.find_first_of(':',debut);
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();
578 compo->checkInputFilesToService(_method.c_str());
580 catch( const SALOME::SALOME_Exception& ex )
582 std::string text="Execution problem in checkInputFilesToService: ";
583 text += (const char*)ex.details.text;
585 throw Exception(text);
587 catch(CORBA::SystemException& ex)
589 std::string msg="Execution problem: component probably does not support files ??";
591 throw Exception(msg);
595 DEBTRACE( "+++++++++++++++++SalomeNode::outputs+++++++++++++++++" )
596 list<OutputPort *>::iterator iter;
597 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
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))
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 );
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);
616 req->exceptions()->add(SALOME::_tc_SALOME_Exception);
618 DEBTRACE( "+++++++++++++++++SalomeNode::calculation+++++++++++++++++" << _method )
620 CORBA::Exception *exc =req->env()->exception();
623 DEBTRACE( "An exception was thrown!" )
624 DEBTRACE( "The raised exception is of Type:" << exc->_name() )
626 CORBA::SystemException* sysexc;
627 sysexc=CORBA::SystemException::_downcast(exc);
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")
637 text=text+"component '" +_ref+ "' has no service '" + _method+ "'";
641 text=text+"System Exception "+ excname;
644 throw Exception(text);
647 // Not a System Exception
648 CORBA::UnknownUserException* userexc;
649 userexc=CORBA::UnknownUserException::_downcast(exc);
652 CORBA::Any anyExcept = userexc->exception();
654 const SALOME::SALOME_Exception* salexc;
655 if(anyExcept >>= salexc)
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() );
662 std::string msg="Execution problem: User Exception occurred";
664 throw Exception(msg);
666 std::string msg="Execution problem";
668 throw Exception(msg);
671 DEBTRACE( "++++++++++++SalomeNode::outputs++++++++++++" )
672 int out_param=in_param;
673 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
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))
681 CORBA::Any *ob=arguments->item(out_param)->value();
683 switch(p->edGetType()->kind())
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.
708 out_param=out_param+1;
713 DEBTRACE("checkOutputFilesToService: " << _method);
716 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
718 OutputCorbaPort *p=(OutputCorbaPort *)*iter;
719 if(!p->edGetType()->isA(Runtime::_tc_file))
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)
728 debut=filename.find_first_of(':',debut);
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());
738 compo->checkOutputFilesToService(_method.c_str());
740 catch( const SALOME::SALOME_Exception& ex )
742 std::string text=(const char*)ex.details.text;
744 throw Exception("Execution problem in checkOutputFilesToService: " + text);
746 catch(CORBA::SystemException& ex)
748 std::string msg="Execution problem: component probably does not support files ?";
750 throw Exception(msg);
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() << " +++++++++++++++++" )
759 Node *SalomeNode::simpleClone(ComposedNode *father, bool editionOnly) const
761 return new SalomeNode(*this,father);
764 //! Create a SalomeNode with the same component object and no input or output port
766 * \param name : node name
767 * \return a new SalomeNode node
769 ServiceNode* SalomeNode::createNode(const std::string& name)
771 SalomeNode* node=new SalomeNode(name);
772 node->setComponent(_component);
776 std::string SalomeNode::getContainerLog()
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) )
783 Engines::Container_var cont= compo->GetContainerRef();
784 CORBA::String_var logname = cont->logfilename();
787 std::string::size_type pos = msg.find(":");
788 msg=msg.substr(pos+1);