Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

ToolSvc.cpp

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiSvc/src/ToolSvc/ToolSvc.cpp,v 1.1.1.3 2001/04/18 18:32:51 tlindner Exp $
00002 
00003 // Include Files
00004 #include "GaudiKernel/MsgStream.h"
00005 #include "GaudiKernel/ISvcLocator.h"
00006 #include "GaudiKernel/Algorithm.h"
00007 #include "GaudiKernel/Service.h"
00008 #include "GaudiKernel/SvcFactory.h"
00009 #include "GaudiKernel/IToolFactory.h"
00010 #include "GaudiKernel/GaudiException.h"
00011 #include "GaudiKernel/AlgTool.h"
00012 #include "ToolSvc.h"
00013 
00014 // Instantiation of a static factory class used by clients to create
00015 //  instances of this service
00016 static SvcFactory<ToolSvc> s_factory;
00017 const ISvcFactory& ToolSvcFactory = s_factory;
00018 
00019 
00020 //
00021 // ClassName:   ToolSvc
00022 //  
00023 // Description: This service manages tools. 
00024 //              Tools can be common, in which case a single instance
00025 //              can be shared by different algorithms, or private
00026 //              in which case it is necessary to specify the parent
00027 //              when requesting it.
00028 //              The service has a list of instanciated tools and if
00029 //              an already existing tool is requested the existing
00030 //              instance is passed.
00031 //              The parent of a tool can be an algortihm or a service.
00032 //              The environment of a tool can be set by using that of
00033 //              the parent. A common tool is considered to belong to the
00034 //              ToolSvc itself.
00035 //
00036 // Author:      G.Corti, P.Mato
00037 //------------------------------------------------------------------
00038 
00039 
00040 // Standard Constructor.
00041 //   Input:  name   String with service name
00042 //   Input:  svc    Pointer to service locator interface
00043 ToolSvc::ToolSvc( const std::string& name, ISvcLocator* svc )
00044 : Service(name, svc) {
00045   m_objManager = 0;
00046   m_instancesTools = new ListTools();
00047 
00048 }
00049   
00050 // Destructor.
00051 ToolSvc::~ToolSvc() { 
00052   delete m_instancesTools;
00053 }
00054 
00055 // Inherited Service overrides:
00056 //
00057   // Initialize the service.
00058 StatusCode ToolSvc::initialize() {
00059 
00060   // initialize the Service Base class
00061   StatusCode status = Service::initialize();
00062 
00063   MsgStream log( msgSvc(), name() ); 
00064 
00065   if ( status.isFailure() ) {
00066     log << MSG::ERROR << "Unable to initialize the Service" << endreq;
00067     return status;
00068   }
00069 
00070   // set my own (ToolSvc) properties via the jobOptionService 
00071   setProperties();
00072 
00073   // locate Object Manager to locate later the tools 
00074   status = serviceLocator()->getService("ApplicationMgr", IID_IObjManager,
00075                                         reinterpret_cast<IInterface*&>( m_objManager ));
00076   if( status.isFailure()) {
00077     log << MSG::ERROR << "Unable to locate ObjectManager Service" << endreq;
00078     return status;
00079   }
00080 
00081   return StatusCode::SUCCESS;
00082 }
00083   
00084   // Finalise the service.
00085 StatusCode ToolSvc::finalize() {
00086   MsgStream log( msgSvc(), name() ); 
00087 
00088   // Remove all the tool instances from the list of instanciated
00089   // tools and release the tools themselves.
00090   log << MSG::INFO << "Removing all tools created by ToolSvc" << endreq;
00091   while ( m_instancesTools->size() > 0 ) {
00092     IAlgTool* itool = m_instancesTools->back();
00093     log << MSG::DEBUG << "Removing tool " << (m_instancesTools->back())->name() << endreq;
00094     m_instancesTools->pop_back();
00095     itool->release();
00096   }
00097 
00098   // Finalize this specific service
00099   StatusCode status = Service::finalize();
00100   return status;
00101 }
00102   
00103   // Query the interfaces.
00104   //   Input: riid, Requested interface ID
00105   //          ppvInterface, Pointer to requested interface
00106   //   Return: StatusCode indicating SUCCESS or FAILURE.
00107   // N.B. Don't forget to release the interface after use!!!
00108 StatusCode ToolSvc::queryInterface( const IID& riid, void** ppvInterface ) {
00109   if ( IID_IToolSvc == riid )    {
00110     *ppvInterface = (IToolSvc*)this;
00111   }
00112   else  {
00113     // Interface is not directly available: try out a base class
00114     return Service::queryInterface(riid, ppvInterface);
00115   }
00116   addRef();
00117   return StatusCode::SUCCESS;
00118 }
00119   
00120 // IToolSvc interfaces overwrite
00121 // 
00122   // Retrieve tool, create it by default as common tool if it does not already exist.
00123   // The user provided part of the name is assumed to be the concrete class
00124 StatusCode ToolSvc::retrieve(const std::string& tooltype, IAlgTool*& tool, const IInterface* parent=0, 
00125                                  bool createIf=true) {
00126 
00127   std::string toolname = tooltype;
00128   return retrieve(tooltype, toolname, tool, parent, createIf);
00129 }
00130 
00131   // Retrieve tool, but with a name, this allow to have many instances of the
00132   // same tool with different properties
00133 StatusCode ToolSvc::retrieve(const std::string& tooltype, const std::string& toolname,  
00134                                  IAlgTool*& tool, const IInterface* parent=0, bool createIf=true) {
00135 
00136   MsgStream log( msgSvc(), name() );
00137   
00138   // If parent is not specified it means it is the ToolSvc itself
00139   if( 0 == parent ) {
00140     parent = this;
00141   }
00142   std::string fullname = nameTool( toolname, parent );  
00143 
00144   // Find tool in list of those already existing, and tell its interface that it has
00145   // been used one more time
00146   ListTools::const_iterator it;
00147   for( it = m_instancesTools->begin(); it != m_instancesTools->end(); it++ ) {
00148     if( (*it)->name() == fullname ) {
00149       log << MSG::DEBUG << "Retrieved tool" << toolname << endreq;
00150       tool = *it;
00151       // Do we need to add references when a new retrieve is done ???
00152       // In that case we can keep the number of references to the same instance...
00153       // unsigned long count = tool->addRef();
00154       return StatusCode::SUCCESS;
00155     }
00156   } 
00157   
00158   // Instances of this tool do not exist, create an instance if desired otherwise
00159   // return failure
00160   if( !createIf ) {
00161     log << MSG::ERROR << "Tool " << toolname << " not found and creation not requested" 
00162         << endreq;
00163     return StatusCode::FAILURE;
00164   }
00165     
00166   return create( tooltype, toolname, parent, tool );
00167 }
00168 
00169 
00170 // Methods not in the IToolSvc interface 
00171 //
00172   // Create a Tool "belonging" to the parent with automatically assigned name
00173 StatusCode ToolSvc::create(const std::string& tooltype, const IInterface* parent, IAlgTool*& tool) {
00174 
00175   std::string toolname = tooltype;
00176   return create( tooltype, toolname, parent, tool);
00177 }
00178 
00179   // Create a Tool "belonging" to the parent algorithm with specified name
00180 StatusCode ToolSvc::create(const std::string& tooltype, const std::string& toolname, 
00181                            const IInterface* parent, IAlgTool*& tool) {
00182   MsgStream log( msgSvc(), name() );
00183   
00184   StatusCode sc;
00185   const IFactory* factory = 0;
00186   IToolFactory* toolfactory = 0;
00187    
00188   // If parent has not been specified, assume it is the ToolSvc 
00189   if ( 0 == parent ) {
00190     parent = this; 
00191   }
00192 
00193   tool = 0;
00194 
00195   // Check if the tool already exist : this should never happen
00196   std::string fullname = nameTool(toolname, parent);
00197   if( existsTool( fullname ) ) {
00198     log << MSG::ERROR << "Tool " << fullname << " already exists" << endreq;
00199     return StatusCode::FAILURE;
00200   }
00201 
00202   // Find the factory and check if it is of the right type, set the properties of the
00203   // tool
00204   if( m_objManager->existsObjFactory( tooltype ) ) {
00205     factory = m_objManager->objFactory( tooltype );
00206     IFactory* fact = const_cast<IFactory*>(factory);
00207     sc = fact->queryInterface( IID_IToolFactory, (void**)&toolfactory );
00208     if( sc.isFailure() ) {
00209       log << MSG::ERROR <<"Found a Factory for " << tooltype << " but is not a Tool factory" << endreq;
00210       return sc;
00211     }
00212     // instanciate the tool using the factory
00213     try {
00214       tool = toolfactory->instantiate( fullname, parent );
00215     }
00216     catch ( const GaudiException& Exception )  {
00217             // (1) perform the printout of message
00218             MsgStream log ( msgSvc() , name() + " retriving tool " + tooltype );
00219             log << MSG::ERROR << " Exception with tag=" << Exception.tag() << " is caught " << endreq;
00220       // (2) print  the exception itself (NB!  - GaudiException is a linked list of all "previous exceptions")
00221             log << MSG::ERROR << Exception  << endreq;
00222       tool = 0;
00223       return StatusCode::FAILURE;
00224     }
00225     catch( const std::exception& Exception ) {
00226             // (1) perform the printout of message
00227             MsgStream log ( msgSvc() , name() + " retriving tool " + tooltype );
00228             log << MSG::FATAL << " Standard std::exception is caught " << endreq;
00229             // (2) print  the exception itself (NB!  - GaudiException is a linked list of all "previous exceptions")
00230             log << MSG::ERROR << Exception.what()  << endreq;
00231       tool = 0;
00232       return StatusCode::FAILURE;
00233     }
00234     catch(...) {
00235             // (1) perform the printout
00236             MsgStream log ( msgSvc() , name() + " retriving tool " + tooltype );
00237             log << MSG::FATAL << "UNKNOWN Exception is caught " << endreq;
00238             tool = 0;
00239       return StatusCode::FAILURE;
00240     }
00241 
00242     m_instancesTools->push_back( tool );
00243 
00244     // Since only AlgTool has the setProperties() method it is necessary to cast 
00245     // to the base class in order to set the properties via the JobOptions service
00246     AlgTool* mytool = dynamic_cast<AlgTool*> (tool);
00247     if ( mytool != 0 ) { 
00248       mytool->setProperties();
00249     }
00250     return StatusCode::SUCCESS;
00251     log << MSG::INFO << "Tool " << fullname << " created" << endreq;  
00252   }
00253   else {
00254     log << MSG::ERROR << "Factory for Tool " << tooltype << " not found" << endreq;
00255     return StatusCode::FAILURE;
00256   }
00257 }
00258 
00259   // tells what will be the complete tool name
00260 std::string ToolSvc::nameTool(const std::string& toolname, const IInterface* parent) {
00261   
00262   MsgStream log ( msgSvc(), name() );
00263   std::string fullname = "";
00264   if( parent == 0 ) {
00265     fullname = this->name() + "." + toolname;
00266     return fullname;
00267   }
00268   else {    
00269     std::string prefname = "";
00270     // Query the parent interface to check if it is an algorithm or a service
00271     StatusCode sc;
00272     IInterface* cparent = const_cast<IInterface*>(parent);
00273     // ... is it an algorithm ?
00274     IAlgorithm* parentAlg = 0;
00275     sc = cparent->queryInterface( IID_IAlgorithm, (void**)&parentAlg );
00276     if ( sc.isSuccess() ) {
00277       prefname = parentAlg->name();
00278       parentAlg->release();
00279     }
00280     // ... since it is not an algorithm maybe it is a service
00281     else {
00282       IService* parentSvc = 0;
00283       sc = cparent->queryInterface( IID_IService, (void**)&parentSvc );
00284       if ( sc.isSuccess() ) {
00285         prefname = parentSvc->name();
00286         parentSvc->release();
00287       }
00288       else {
00289         log << MSG::ERROR << "Parent for tools can only be an Algorithm or a Service" << endreq;
00290       }
00291     }
00292      
00293    return fullname = prefname + "." + toolname;
00294   }
00295 }
00296 
00297 
00298 // existsTool
00299 bool ToolSvc::existsTool( const std::string& fullname) const {
00300   ListTools::const_iterator it;
00301   for (it = m_instancesTools->begin(); it != m_instancesTools->end(); it++ ) {
00302           if( (*it)->name() == fullname ) {
00303       return true;
00304     }
00305   }
00306   return false;
00307 }
00308 
00309 

Generated at Wed Nov 21 12:22:31 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000