1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SALOME Container : implementation of container and engine for Kernel
24 // File : Component_i.cxx
25 // Author : Paul RASCLE, EDF - MARC TAJCHMAN, CEA
28 //#define private protected // for pd_refCount trace
30 #include "SALOME_Component_i.hxx"
31 #include "SALOME_Container_i.hxx"
32 #include "RegistryConnexion.hxx"
33 #include "Basics_Utils.hxx"
39 #include "utilities.h"
43 #include <sys/resource.h>
46 #include <sys/timeb.h>
51 extern bool _Sleeping ;
52 static Engines_Component_i * theEngines_Component ;
54 bool Engines_Component_i::_isMultiInstance = false;
56 /*! \class Engines_Component_i
57 * \brief C++ implementation of Engines::Component interface
61 //=============================================================================
63 * Default constructor, not for use
65 //=============================================================================
67 Engines_Component_i::Engines_Component_i():_myConnexionToRegistry(0), _notifSupplier(0), _id(0)
70 MESSAGE("Default Constructor, not for normal use...");
73 //=============================================================================
74 /*! \brief Standard Constructor for generic Component, used in derived class
76 * Connection to Registry and Notification
77 * \param orb Object Request broker given by Container
78 * \param poa Portable Object Adapter from Container (normally root_poa)
79 * \param contId container CORBA id inside the server
80 * \param instanceName unique instance name for this object (see Container_i)
81 * \param interfaceName component class name
82 * \param notif use of notification
83 * \param regist (true or false) use of registry (default true)
85 //=============================================================================
87 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
88 PortableServer::POA_ptr poa,
89 PortableServer::ObjectId * contId,
90 const char *instanceName,
91 const char *interfaceName,
94 _instanceName(instanceName),
95 _interfaceName(interfaceName),
96 _myConnexionToRegistry(0),
105 _CanceledThread(false)
107 MESSAGE("Component constructor with instanceName "<< _instanceName);
108 _orb = CORBA::ORB::_duplicate(orb);
109 _poa = PortableServer::POA::_duplicate(poa);
111 CORBA::Object_var o = _poa->id_to_reference(*contId); // container ior...
112 _container=Engines::Container::_narrow(o);
117 const CORBA::String_var ior = _orb->object_to_string(o);
118 _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession",
119 _instanceName.c_str());
123 _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
126 //=============================================================================
127 /*! \brief Standard Constructor for standalone Component, used in derived class
129 * Connection to Registry and Notification
130 * \param orb Object Request broker given by Container
131 * \param poa Portable Object Adapter from Container (normally root_poa)
132 * \param container container CORBA reference
133 * \param instanceName unique instance name for this object (see Container_i)
134 * \param interfaceName component class name
135 * \param notif use of notification
136 * \param regist (true or false) use of registry (default true)
138 //=============================================================================
140 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
141 PortableServer::POA_ptr poa,
142 Engines::Container_ptr container,
143 const char *instanceName,
144 const char *interfaceName,
147 _instanceName(instanceName),
148 _interfaceName(interfaceName),
149 _myConnexionToRegistry(0),
158 _CanceledThread(false)
160 MESSAGE("Component constructor with instanceName "<< _instanceName);
161 _orb = CORBA::ORB::_duplicate(orb);
162 _poa = PortableServer::POA::_duplicate(poa);
163 _container=Engines::Container::_duplicate(container);
165 const CORBA::String_var ior = _orb->object_to_string(_container);
168 _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession", _instanceName.c_str());
171 _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
176 //=============================================================================
178 * Destructor: call Container for decrement of instances count.
179 * When instances count falls to 0, the container tries to remove the
180 * component library (dlclose)
182 //=============================================================================
184 Engines_Component_i::~Engines_Component_i()
186 MESSAGE("Component destructor");
187 Engines_Container_i::decInstanceCnt(_interfaceName);
188 if(_myConnexionToRegistry)delete _myConnexionToRegistry;
189 _myConnexionToRegistry = 0 ;
196 SCRUTE(_notifSupplier->_refcount_value());
197 PortableServer::POA_var poa=_notifSupplier->_default_POA();
198 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(_notifSupplier);
199 poa->deactivate_object(anObjectId.in());
200 SCRUTE(_notifSupplier->_refcount_value());
201 _notifSupplier->_remove_ref();
205 //=============================================================================
207 * CORBA method: return name of the instance, unique in this Container
209 //=============================================================================
211 char* Engines_Component_i::instanceName()
213 return CORBA::string_dup(_instanceName.c_str()) ;
216 //=============================================================================
218 * CORBA method: return name of the component class
220 //=============================================================================
222 char* Engines_Component_i::interfaceName()
224 return CORBA::string_dup(_interfaceName.c_str()) ;
227 //=============================================================================
229 * CORBA method: Test if instance is alive and responds
231 //=============================================================================
233 void Engines_Component_i::ping()
236 MESSAGE("Engines_Component_i::ping() pid "<< getpid() << " threadid "
239 MESSAGE("Engines_Component_i::ping() pid "<< _getpid()<< " threadid "
240 << pthread_self().p );
244 //=============================================================================
246 * CORBA method: Deactivate this instance. CORBA object is deactivated (do not
247 * respond any more to CORBA calls), the connection to Regsitry is removed
248 * (Registry informed of deactivation), internal server reference counter on
249 * the derived servant class is decremented, to allow destruction of the class
250 * (delete) by POA, when there are no more references.
251 * -- TO BE USED BY CONTAINER ONLY (Container housekeeping) --
253 //=============================================================================
255 void Engines_Component_i::destroy()
257 MESSAGE("Engines_Component_i::destroy()");
258 //SCRUTE(_refcount_value());
259 _poa->deactivate_object(*_id);
260 //SCRUTE(_refcount_value());
262 //SCRUTE(_refcount_value());
263 MESSAGE("Engines_Component_i::destroyed") ;
266 //=============================================================================
268 * CORBA method: return CORBA reference of the Container
271 //=============================================================================
273 Engines::Container_ptr Engines_Component_i::GetContainerRef()
275 return Engines::Container::_duplicate(_container);
278 //=============================================================================
281 * Gives a sequence of (key=string,value=any) to the component.
282 * Base class component stores the sequence in a map.
283 * The map is cleared before.
284 * This map is for use by derived classes.
285 * \param dico sequence of (key=string,value=any)
287 //=============================================================================
289 void Engines_Component_i::setProperties(const Engines::FieldsDict& dico)
292 for (CORBA::ULong i=0; i<dico.length(); i++)
294 std::string cle(dico[i].key);
295 _fieldsDict[cle] = dico[i].value;
299 //=============================================================================
302 * returns a previously stored map (key=string,value=any) as a sequence.
303 * (see setProperties)
305 //=============================================================================
307 Engines::FieldsDict* Engines_Component_i::getProperties()
309 Engines::FieldsDict_var copie = new Engines::FieldsDict;
310 copie->length(_fieldsDict.size());
311 std::map<std::string,CORBA::Any>::iterator it;
313 for (it = _fieldsDict.begin(); it != _fieldsDict.end(); it++, i++)
315 std::string cle((*it).first);
316 copie[i].key = CORBA::string_dup(cle.c_str());
317 copie[i].value = _fieldsDict[cle];
319 return copie._retn();
322 //=============================================================================
325 * This method is to set an option specific to a certain EngineComponent.
327 //=============================================================================
329 void Engines_Component_i::SetOption(const char*, const char*)
333 //=============================================================================
336 * This method is to get value of an option specific to a certain EngineComponent.
338 //=============================================================================
340 char* Engines_Component_i::GetOption(const char*)
342 return CORBA::string_dup("") ;
345 //=============================================================================
347 * CORBA method: used by Supervision to give names to this instance
349 //=============================================================================
351 void Engines_Component_i::Names( const char * graphName ,
352 const char * nodeName )
354 _graphName = graphName ;
355 _nodeName = nodeName ;
356 // MESSAGE("Engines_Component_i::Names( '" << _graphName << "' , '"
357 // << _nodeName << "' )");
360 //=============================================================================
362 * CORBA method: used in Supervision
364 //=============================================================================
366 bool Engines_Component_i::Kill_impl()
368 // MESSAGE("Engines_Component_i::Kill_i() pthread_t "<< pthread_self()
369 // << " pid " << getpid() << " instanceName "
370 // << _instanceName.c_str() << " interface " << _interfaceName.c_str()
371 // << " machineName " << Kernel_Utils::GetHostname().c_str()<< " _id " << hex << _id
372 // << dec << " _ThreadId " << _ThreadId << " this " << hex << this
375 bool RetVal = false ;
377 if ( _ThreadId > 0 && pthread_self() != _ThreadId )
379 RetVal = Killer( _ThreadId , SIGUSR2 ) ;
380 _ThreadId = (pthread_t ) -1 ;
384 if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
386 RetVal = Killer( *_ThreadId , 0 ) ;
387 _ThreadId = (pthread_t* ) 0 ;
394 //=============================================================================
396 * CORBA method: used in Supervision
398 //=============================================================================
400 bool Engines_Component_i::Stop_impl()
403 MESSAGE("Engines_Component_i::Stop_i() pthread_t "<< pthread_self()
404 << " pid " << getpid() << " instanceName "
405 << _instanceName.c_str() << " interface " << _interfaceName.c_str()
406 << " machineName " << Kernel_Utils::GetHostname().c_str()<< " _id " << std::hex << _id
407 << std::dec << " _ThreadId " << _ThreadId );
409 MESSAGE("Engines_Component_i::Stop_i() pthread_t "<< pthread_self().p
410 << " pid " << _getpid() << " instanceName "
411 << _instanceName.c_str() << " interface " << _interfaceName.c_str()
412 << " machineName " << Kernel_Utils::GetHostname().c_str()<< " _id " << std::hex << _id
413 << std::dec << " _ThreadId " << _ThreadId );
417 bool RetVal = false ;
419 if ( _ThreadId > 0 && pthread_self() != _ThreadId )
421 RetVal = Killer( _ThreadId , 0 ) ;
422 _ThreadId = (pthread_t ) -1 ;
425 if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
427 RetVal = Killer( *_ThreadId , 0 ) ;
428 _ThreadId = (pthread_t* ) 0 ;
434 //=============================================================================
436 * CORBA method: used in Supervision
438 //=============================================================================
440 bool Engines_Component_i::Suspend_impl()
443 MESSAGE("Engines_Component_i::Suspend_i() pthread_t "<< pthread_self()
444 << " pid " << getpid() << " instanceName "
445 << _instanceName.c_str() << " interface " << _interfaceName.c_str()
446 << " machineName " << Kernel_Utils::GetHostname().c_str()<< " _id " << std::hex << _id
447 << std::dec << " _ThreadId " << _ThreadId );
449 MESSAGE("Engines_Component_i::Suspend_i() pthread_t "<< pthread_self().p
450 << " pid " << _getpid() << " instanceName "
451 << _instanceName.c_str() << " interface " << _interfaceName.c_str()
452 << " machineName " << Kernel_Utils::GetHostname().c_str()<< " _id " << std::hex << _id
453 << std::dec << " _ThreadId " << _ThreadId );
456 bool RetVal = false ;
458 if ( _ThreadId > 0 && pthread_self() != _ThreadId )
460 if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
470 RetVal = Killer( _ThreadId ,SIGINT ) ;
472 RetVal = Killer( *_ThreadId ,SIGINT ) ;
474 //if ( RetVal ) _Sleeping = true;
481 //=============================================================================
483 * CORBA method: used in Supervision
485 //=============================================================================
487 bool Engines_Component_i::Resume_impl()
490 MESSAGE("Engines_Component_i::Resume_i() pthread_t "<< pthread_self()
491 << " pid " << getpid() << " instanceName "
492 << _instanceName.c_str() << " interface " << _interfaceName.c_str()
493 << " machineName " << Kernel_Utils::GetHostname().c_str()<< " _id " << std::hex << _id
494 << std::dec << " _ThreadId " << _ThreadId );
496 MESSAGE("Engines_Component_i::Resume_i() pthread_t "<< pthread_self().p
497 << " pid " << _getpid() << " instanceName "
498 << _instanceName.c_str() << " interface " << _interfaceName.c_str()
499 << " machineName " << Kernel_Utils::GetHostname().c_str()<< " _id " << std::hex << _id
500 << std::dec << " _ThreadId " << _ThreadId );
502 bool RetVal = false ;
504 if ( _ThreadId > 0 && pthread_self() != _ThreadId )
506 if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
522 //=============================================================================
526 //=============================================================================
528 CORBA::Long Engines_Component_i::CpuUsed_impl()
531 if ( _ThreadId || _Executed )
536 if ( pthread_self() != _ThreadId )
538 if ( pthread_self().p != _ThreadId->p )
546 // Get Cpu in the appropriate thread with that object !...
547 theEngines_Component = this ;
549 Killer( _ThreadId ,SIGUSR1 ) ;
551 Killer( *_ThreadId ,SIGUSR11 ) ;
554 cpu = _ThreadCpuUsed ;
558 _ThreadCpuUsed = CpuUsed() ;
559 cpu = _ThreadCpuUsed ;
560 // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
561 // << _serviceName << " " << cpu << endl ;
566 cpu = _ThreadCpuUsed ;
567 // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
568 // << _serviceName << " " << cpu<< endl ;
573 // cout<< pthread_self()<<"Engines_Component_i::CpuUsed_impl _ThreadId "
574 // <<_ThreadId <<" "<<_serviceName<<" _StartUsed "<<_StartUsed<<endl;
580 //=============================================================================
582 * C++ method: return Container Servant
584 //=============================================================================
586 Engines_Container_i *Engines_Component_i::GetContainerPtr()
588 PortableServer::ObjectId_var contId=_poa->reference_to_id(_container);
589 return dynamic_cast<Engines_Container_i*>(_poa->id_to_servant(contId)) ;
592 //=============================================================================
594 * C++ method: return CORBA instance id, the id is set in derived class
595 * constructor, when instance is activated.
597 //=============================================================================
599 PortableServer::ObjectId * Engines_Component_i::getId()
601 // MESSAGE("PortableServer::ObjectId * Engines_Component_i::getId()");
605 //=============================================================================
607 * C++ method: used by derived classes for supervision
609 //=============================================================================
611 void Engines_Component_i::beginService(const char *serviceName)
613 std::cerr << "beginService for " << serviceName << " Component instance : " << _instanceName << std::endl;
616 _ThreadId = pthread_self() ;
618 _ThreadId = new pthread_t;
619 _ThreadId->p = pthread_self().p ;
620 _ThreadId->x = pthread_self().x ;
623 _StartUsed = CpuUsed_impl() ;
626 _serviceName = serviceName ;
627 theEngines_Component = this ;
628 if ( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS , NULL ) )
630 perror("pthread_setcanceltype ") ;
633 if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , NULL ) )
635 perror("pthread_setcancelstate ") ;
639 // --- all strings given with setProperties are set in environment
640 std::map<std::string,CORBA::Any>::iterator it;
641 for (it = _fieldsDict.begin(); it != _fieldsDict.end(); it++)
643 std::string cle((*it).first);
644 if ((*it).second.type()->kind() == CORBA::tk_string)
647 (*it).second >>= value;
651 putenv((char *)s.c_str());
652 MESSAGE("--- setenv: "<<cle<<" = "<< value);
657 //=============================================================================
659 * C++ method: used by derived classes for supervision
661 //=============================================================================
663 void Engines_Component_i::endService(const char *serviceName)
665 if ( !_CanceledThread )
666 _ThreadCpuUsed = CpuUsed_impl() ;
668 float cpus=_ThreadCpuUsed/1000.;
669 std::cerr << "endService for " << serviceName << " Component instance : " << _instanceName ;
670 std::cerr << " Cpu Used: " << cpus << " (s) " << std::endl;
671 MESSAGE("Send EndService notification for " << serviceName
672 << std::endl << " Component instance : " << _instanceName << " StartUsed "
673 << _StartUsed << " _ThreadCpuUsed "<< _ThreadCpuUsed << std::endl <<std::endl);
677 //=============================================================================
679 * C++ method: -- CHECK IF USED --
681 //=============================================================================
683 char* Engines_Component_i::graphName()
685 return CORBA::string_dup( _graphName.c_str() ) ;
688 //=============================================================================
690 * C++ method: -- CHECK IF USED --
692 //=============================================================================
694 char* Engines_Component_i::nodeName()
696 return CORBA::string_dup( _nodeName.c_str() ) ;
699 //=============================================================================
701 * C++ method: used in Supervision (see kill_impl)
703 //=============================================================================
705 bool Engines_Component_i::Killer( pthread_t ThreadId , int signum )
715 if ( pthread_cancel( ThreadId ) )
717 perror("Killer pthread_cancel error") ;
723 MESSAGE("Killer : ThreadId " << ThreadId.p << " pthread_canceled") ;
725 MESSAGE("Killer : ThreadId " << ThreadId << " pthread_canceled") ;
731 if ( pthread_kill( ThreadId , signum ) == -1 )
733 perror("Killer pthread_kill error") ;
739 MESSAGE("Killer : ThreadId " << ThreadId.p << " pthread_killed(" << signum << ")") ;
741 MESSAGE("Killer : ThreadId " << ThreadId << " pthread_killed(" << signum << ")") ;
750 void CallCancelThread();
752 //=============================================================================
756 //=============================================================================
760 if ( theEngines_Component )
761 theEngines_Component->SetCurCpu() ;
764 //=============================================================================
768 //=============================================================================
770 void Engines_Component_i::SetCurCpu()
772 _ThreadCpuUsed = CpuUsed() ;
773 // MESSAGE(pthread_self() <<
774 // " Engines_Component_i::SetCurCpu() _ThreadCpuUsed " << _ThreadCpuUsed) ;
777 //=============================================================================
781 //=============================================================================
783 long Engines_Component_i::CpuUsed()
787 struct rusage usage ;
788 if ( _ThreadId || _Executed )
790 if ( getrusage( RUSAGE_SELF , &usage ) == -1 )
792 perror("Engines_Component_i::CpuUsed") ;
795 //cpu time is calculated in millisecond (user+system times)
796 cpu = usage.ru_utime.tv_sec*1000 +usage.ru_utime.tv_usec/1000;
797 cpu = cpu+ usage.ru_stime.tv_sec*1000 +usage.ru_stime.tv_usec/1000;
799 // std::cout << pthread_self() << " Engines_Component_i::CpuUsed " << " "
800 // << _serviceName << usage.ru_utime.tv_sec << " - " << _StartUsed
801 // << " = " << cpu << std::endl ;
805 // std::cout << pthread_self() << "Engines_Component_i::CpuUsed _ThreadId "
806 // << _ThreadId << " " << _serviceName<< " _StartUsed "
807 // << _StartUsed << std::endl ;
810 // NOT implemented yet
817 void CallCancelThread()
819 if ( theEngines_Component )
820 theEngines_Component->CancelThread() ;
823 //=============================================================================
827 //=============================================================================
829 void Engines_Component_i::CancelThread()
831 _CanceledThread = true;
834 //=============================================================================
836 * C++ method: Send message to event channel
838 //=============================================================================
840 void Engines_Component_i::sendMessage(const char *event_type,
843 _notifSupplier->Send(_graphName.c_str(), _nodeName.c_str(), event_type, message);
846 //=============================================================================
848 * C++ method: return standard library name built on component name
850 //=============================================================================
852 std::string Engines_Component_i::GetDynLibraryName(const char *componentName)
854 std::string prefix, suffix;
855 std::string cname = componentName;
861 #elif defined(__APPLE__)
866 std::string ret = prefix + cname + std::string("Engine.") + suffix;
870 //=============================================================================
872 * C++ method: DumpPython default implementation
874 //=============================================================================
876 Engines::TMPFile* Engines_Component_i::DumpPython(CORBA::Boolean isPublished,
877 CORBA::Boolean isMultiFile,
878 CORBA::Boolean& isValidScript)
880 const char* aScript = isMultiFile ? "def RebuildData(): pass" : "";
881 char* aBuffer = new char[strlen(aScript)+1];
882 strcpy(aBuffer, aScript);
883 CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer;
884 int aBufferSize = strlen(aBuffer)+1;
885 Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aBufferSize, aBufferSize, anOctetBuf, 1);
886 isValidScript = true;
887 return aStreamFile._retn();
890 Engines::Salome_file_ptr
891 Engines_Component_i::getInputFileToService(const char* service_name,
892 const char* Salome_file_name)
894 // Try to find the service, if it doesn't exist, we throw an exception.
895 _Service_file_map_it = _Input_Service_file_map.find(service_name);
896 if (_Service_file_map_it == _Input_Service_file_map.end()) {
897 SALOME::ExceptionStruct es;
898 es.type = SALOME::INTERNAL_ERROR;
899 es.text = "service doesn't have salome files";
900 throw SALOME::SALOME_Exception(es);
902 _t_Salome_file_map * _map = _Input_Service_file_map[service_name];
904 // Try to find the Salome_file ...
905 _Salome_file_map_it = _map->find(Salome_file_name);
906 if (_Salome_file_map_it == _map->end()) {
907 SALOME::ExceptionStruct es;
908 es.type = SALOME::INTERNAL_ERROR;
909 es.text = "service doesn't have this Salome_file";
910 throw SALOME::SALOME_Exception(es);
912 Salome_file_i * Sfile = (*_map)[Salome_file_name];
914 return Sfile->_this();
917 Engines::Salome_file_ptr
918 Engines_Component_i::setInputFileToService(const char* service_name,
919 const char* Salome_file_name)
921 // Try to find the service, if it doesn't exist, we add it.
922 _Service_file_map_it = _Input_Service_file_map.find(service_name);
923 if (_Service_file_map_it == _Input_Service_file_map.end()) {
924 _t_Salome_file_map * _map = new _t_Salome_file_map();
925 _Input_Service_file_map[service_name] = _map;
927 _t_Salome_file_map * _map = _Input_Service_file_map[service_name];
929 // Try to find the Salome_file ...
930 _Salome_file_map_it = _map->find(Salome_file_name);
931 if (_Salome_file_map_it == _map->end()) {
932 Salome_file_i * Sfile = new Salome_file_i();
933 Engines::Container_ptr container = this->GetContainerRef();
934 Sfile->setContainer(Engines::Container::_duplicate(container));
935 (*_map)[Salome_file_name] = Sfile;
938 Salome_file_i * Sfile = (*_map)[Salome_file_name];
939 return Sfile->_this();
943 Engines_Component_i::checkInputFilesToService(const char* service_name)
945 // Try to find the service, if it doesn't exist, nothing to do.
946 _Service_file_map_it = _Input_Service_file_map.find(service_name);
947 if (_Service_file_map_it != _Input_Service_file_map.end()) {
948 _t_Salome_file_map * _map = _Input_Service_file_map[service_name];
949 _t_Salome_file_map::iterator begin = _map->begin();
950 _t_Salome_file_map::iterator end = _map->end();
952 for(;begin!=end;begin++) {
953 Salome_file_i * file = begin->second;
954 std::string file_port_name = begin->first;
955 configureSalome_file(service_name, file_port_name, file);
961 Engines::Salome_file_ptr
962 Engines_Component_i::getOutputFileToService(const char* service_name,
963 const char* Salome_file_name)
965 // Try to find the service, if it doesn't exist, we throw an exception.
966 _Service_file_map_it = _Output_Service_file_map.find(service_name);
967 if (_Service_file_map_it == _Output_Service_file_map.end()) {
968 SALOME::ExceptionStruct es;
969 es.type = SALOME::INTERNAL_ERROR;
970 es.text = "service doesn't have salome files";
971 throw SALOME::SALOME_Exception(es);
973 _t_Salome_file_map * _map = _Output_Service_file_map[service_name];
975 // Try to find the Salome_file ...
976 _Salome_file_map_it = _map->find(Salome_file_name);
977 if (_Salome_file_map_it == _map->end()) {
978 SALOME::ExceptionStruct es;
979 es.type = SALOME::INTERNAL_ERROR;
980 es.text = "service doesn't have this Salome_file";
981 throw SALOME::SALOME_Exception(es);
983 Salome_file_i * Sfile = (*_map)[Salome_file_name];
985 return Sfile->_this();
988 Engines::Salome_file_ptr
989 Engines_Component_i::setOutputFileToService(const char* service_name,
990 const char* Salome_file_name)
992 // Try to find the service, if it doesn't exist, we add it.
993 _Service_file_map_it = _Output_Service_file_map.find(service_name);
994 if (_Service_file_map_it == _Output_Service_file_map.end()) {
995 _t_Salome_file_map * _map = new _t_Salome_file_map();
996 _Output_Service_file_map[service_name] = _map;
998 _t_Salome_file_map * _map = _Output_Service_file_map[service_name];
1000 // Try to find the Salome_file ...
1001 _Salome_file_map_it = _map->find(Salome_file_name);
1002 if (_Salome_file_map_it == _map->end()) {
1003 Salome_file_i * Sfile = new Salome_file_i();
1004 Engines::Container_ptr container = this->GetContainerRef();
1005 Sfile->setContainer(Engines::Container::_duplicate(container));
1006 (*_map)[Salome_file_name] = Sfile;
1009 Salome_file_i * Sfile = (*_map)[Salome_file_name];
1010 return Sfile->_this();
1014 Engines_Component_i::checkOutputFilesToService(const char* service_name)
1016 // Try to find the service, if it doesn't exist, nothing to do.
1017 _Service_file_map_it = _Output_Service_file_map.find(service_name);
1018 if (_Service_file_map_it != _Output_Service_file_map.end()) {
1019 _t_Salome_file_map * _map = _Output_Service_file_map[service_name];
1020 _t_Salome_file_map::iterator begin = _map->begin();
1021 _t_Salome_file_map::iterator end = _map->end();
1023 for(;begin!=end;begin++) {
1024 Salome_file_i * file = begin->second;
1025 std::string file_port_name = begin->first;
1026 configureSalome_file(service_name, file_port_name, file);
1033 //=============================================================================
1035 * C++ method: used to configure the Salome_file into the runtime.
1036 * \param service_name name of the service that use this Salome_file
1037 * \param file_port_name name of the Salome_file
1038 * \param file Salome_file C++ object
1040 //=============================================================================
1042 Engines_Component_i::configureSalome_file(std::string service_name,
1043 std::string file_port_name,
1044 Salome_file_i * file)
1046 // By default this method does nothing
1049 //=============================================================================
1051 * C++ method: return the name of the container associated with this component
1052 * This name does not contains the "/Containers" string and all "/" are replaced by "_"
1053 * \return the container name (reformatted)
1055 //=============================================================================
1056 std::string Engines_Component_i::getContainerName()
1058 return _containerName;
1060 //=============================================================================
1062 * C++ method: set the name of the container associated with this component (attribute _containerName)
1063 * This name does not contains the "/Containers" string and all "/" are replaced by "_"
1064 * \return the container name (reformatted)
1066 //=============================================================================
1067 void Engines_Component_i::setContainerName()
1069 CORBA::String_var containerName=_container->name();
1070 std::string name(containerName);
1072 std::string::size_type slash =name.find_first_of('/');
1073 if(slash != std::string::npos)
1075 _containerName=name;
1078 //=============================================================================
1080 \brief Get version of the component
1082 This method is supposed to be implemented in all derived classes; default implementation
1083 returns empty string that means that no version information about the component is available.
1085 \note The version of the component is stored to the study, as a part of general persistence
1086 mechanism; once stored, version information in the study cannot be changed.
1088 \return string containing component's version, e.g. "1.0"
1090 char* Engines_Component_i::getVersion()
1092 return CORBA::string_dup( "" );