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

DLLClassManager.cpp

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiSvc/src/ApplicationMgr/DLLClassManager.cpp,v 1.1.1.3 2001/04/18 18:32:48 tlindner Exp $
00002 
00003 // Include files
00004 #include "GaudiKernel/IFactory.h"
00005 #include "GaudiKernel/ISvcLocator.h"
00006 #include "GaudiKernel/IAlgManager.h"
00007 #include "GaudiKernel/ISvcManager.h"
00008 #include "GaudiKernel/ICnvManager.h"
00009 #include "GaudiKernel/IObjManager.h"
00010 #include "GaudiKernel/IAlgFactory.h"
00011 #include "GaudiKernel/ISvcFactory.h"
00012 #include "GaudiKernel/ICnvFactory.h"
00013 #include "GaudiKernel/FactoryTable.h"
00014 #include "GaudiKernel/ObjectFactory.h"
00015 #include "GaudiKernel/MsgStream.h"
00016 #include "DLLClassManager.h"
00017 #include "GaudiKernel/System.h"
00018 
00019 #include <iostream>
00020 
00021 typedef std::pair<FactoryTable::EntryList*,FactoryTable::EntryList*> TableObject;
00022 class DllTableSpace : public std::map< std::string, TableObject >  {
00023 public:
00024   DllTableSpace();
00025   virtual ~DllTableSpace();
00026   void addDll(const std::string& key, FactoryTable::EntryList* list);
00027   FactoryTable::EntryList* shadow(TableObject& key);
00028 };
00029 
00030 DllTableSpace::DllTableSpace()   {
00031 }
00032 
00033 DllTableSpace::~DllTableSpace()   {
00034   for ( iterator i = begin(); i != end(); i++ )   {
00035     FactoryTable::EntryList* tab    = (*i).second.first;
00036     tab->erase(tab->begin(), tab->end());
00037     delete tab;
00038     tab = (*i).second.second;
00039     tab->erase(tab->begin(), tab->end());
00040     delete tab;
00041     (*i).second.first = (*i).second.second = 0;
00042   }
00043   erase(begin(), end());
00044 }
00045 
00046 FactoryTable::EntryList* DllTableSpace::shadow(TableObject& obj)    {
00047   obj.second->erase(obj.second->begin(), obj.second->end());
00048   for( FactoryTable::EntryList::iterator it = obj.first->begin(); it != obj.first->end(); it++ ) {
00049     obj.second->push_back(*it);
00050   }
00051   return obj.second;
00052 }
00053 
00054 void DllTableSpace::addDll(const std::string& key, FactoryTable::EntryList* list)   {
00055   FactoryTable::EntryList* tab    = new FactoryTable::EntryList(list->begin(), list->end());
00056   FactoryTable::EntryList* shadow = new FactoryTable::EntryList();
00057   this->insert(value_type(key, TableObject(tab, shadow)));
00058 }
00059 
00060 static DllTableSpace s_dllTableSpace;
00061 
00062 // default creator
00063 DLLClassManager::DLLClassManager( ISvcLocator* svclocator ) {
00064   m_svclocator = svclocator;
00065   m_msgsvc     = 0;
00066   m_algmanager = 0;
00067   m_svcmanager = 0;
00068   m_cnvmanager = 0;
00069   m_objmanager = 0;
00070   m_refcount   = 1;
00071 }
00072 
00073 // virtual destructor
00074 DLLClassManager::~DLLClassManager() {
00075 }
00076 
00077 // implementation of IClassManager::declareFactory
00078 StatusCode DLLClassManager::declareFactory( const IFactory& factory ) {
00079   // We need to find out what type of factory we are dealing
00080   StatusCode     sc;
00081   IFactory& fact = const_cast<IFactory&>(factory);
00082 
00083   IAlgFactory* algfactory = 0;
00084   sc = fact.queryInterface( IID_IAlgFactory, (void**)&algfactory );
00085   if( sc.isSuccess() ) {
00086     if( m_algmanager == 0 ) {
00087       sc = m_svclocator->queryInterface( IID_IAlgManager, (void**)&m_algmanager );
00088       if( sc.isFailure() ) return sc;
00089     }
00090 //PM    std::cout << algfactory->algType() << std::endl;
00091     return m_algmanager->declareAlgFactory( *algfactory, algfactory->algType() );
00092   }
00093 
00094   ISvcFactory* svcfactory = 0;
00095   sc = fact.queryInterface( IID_ISvcFactory, (void**)&svcfactory );
00096   if( sc.isSuccess() ) {
00097     if( m_svcmanager == 0 ) {
00098       sc = m_svclocator->queryInterface( IID_ISvcManager, (void**)&m_svcmanager );
00099       if( sc.isFailure() ) return sc;
00100     }
00101 //PM    std::cout << svcfactory->svcType() << std::endl;
00102     return m_svcmanager->declareSvcFactory( *svcfactory, svcfactory->svcType() );
00103   }
00104 
00105   ICnvFactory* cnvfactory = 0;
00106   sc = fact.queryInterface( IID_ICnvFactory, (void**)&cnvfactory );
00107   if( sc.isSuccess() ) {
00108     if( m_cnvmanager == 0 ) {
00109       sc = m_svclocator->queryInterface( IID_ICnvManager, (void**)&m_cnvmanager );
00110       if( sc.isFailure() ) return sc;
00111     }
00112     return m_cnvmanager->declareCnvFactory( *cnvfactory );
00113   }
00114 
00115   // Everything which is not an algorithm, converter or service goes to the default manager
00116   if( m_objmanager == 0 ) {
00117     sc = m_svclocator->queryInterface( IID_IObjManager, (void**)&m_objmanager );
00118     if( sc.isFailure() ) return sc;
00119   }
00120   return m_objmanager->declareObjFactory( factory );
00121 }
00122 
00123 // implementation of IClassManager::loadModule 
00124 StatusCode DLLClassManager::loadModule( const std::string& module ) {
00125   // Access the message service if not yet done already
00126   if( m_msgsvc == 0 ) {
00127     m_svclocator->getService( "MessageSvc", IID_IMessageSvc, (IInterface*&)m_msgsvc );
00128   }
00129   MsgStream log(m_msgsvc, "DllClassManager");
00130 
00131   std::string mod = module=="" ? System::moduleNameFull() : module;
00132   if( module == "NONE" ) return StatusCode::SUCCESS;
00133 
00134   FactoryTable::EntryList* elist = 0;
00135   DllTableSpace::iterator tabIt = s_dllTableSpace.find(mod);
00136   if ( tabIt != s_dllTableSpace.end() )    {
00137     elist = s_dllTableSpace.shadow((*tabIt).second);
00138   }
00139   else if ( module.length() == 0) {
00140     //  A empty module name means current module
00141     elist = FactoryTable::instance()->getEntries();
00142     if ( 0 != elist ) s_dllTableSpace.addDll(mod, elist);
00143   }
00144   else {
00145     void* libHandle = 0;
00146     StatusCode status = System::loadDynamicLib( module, &libHandle);
00147     if ( status.isSuccess() )   {
00148       FactoryTable::GetFunction func;
00149       status = System::getProcedureByName(libHandle, "getFactoryEntries", (System::Creator*)&func);
00150       if ( status.isSuccess() )   {
00151         elist = (func)();
00152         if ( 0 != elist ) s_dllTableSpace.addDll(mod, elist);
00153       }
00154       else    {
00155         // Entry point not found in DLL library
00156         log << MSG::ERROR << "Not found entry point" << endreq;
00157         return StatusCode::FAILURE;      
00158       }
00159     }
00160     else    {
00161       // DLL library not loaded
00162       log << MSG::ERROR << "Not found DLL " << module << endreq;
00163       return StatusCode::FAILURE; 
00164     }
00165   }
00166   if( elist == 0 ) return StatusCode::FAILURE;
00167 
00168   long num = 0;
00169   for( FactoryTable::EntryList::iterator it = elist->begin(); it != elist->end(); it++ ) {
00170     if( m_msgsvc ) {
00171       log << MSG::DEBUG << "Found factory " << (*it)->ident() << endreq;
00172     }
00173     declareFactory( *(*it) );
00174     num++;
00175   }
00176   if( m_msgsvc ) {
00177     log << MSG::INFO << "Loaded " << num << " factories from module "
00178       << ( (module == "")? System::moduleNameFull() : module ) << endreq;
00179   }
00180 
00181   // Clear the factoy table to get ready for next Module load
00182   elist->erase( elist->begin(), elist->end() );
00183   return StatusCode::SUCCESS;
00184 }
00185   
00186 // implmentation of IInterface::addRef
00187 unsigned long DLLClassManager::addRef() {
00188   m_refcount++;
00189         return m_refcount;
00190 }
00191   
00192 // implmentation of IInterface::release
00193 unsigned long DLLClassManager::release() {
00194   m_refcount--;
00195   if( m_refcount <= 0) {
00196     delete this;
00197   }
00198   return m_refcount;
00199 }
00200   
00201 // implementation of IInterface::queryInterface
00202 StatusCode DLLClassManager::queryInterface(const IID& iid, void** pinterface) {
00203   if( iid == IID_IInterface ) {  
00204     *pinterface = (IInterface*)this;
00205   } 
00206   else if ( iid == IID_IClassManager ) {
00207     *pinterface = (IClassManager*)this;
00208   } 
00209   else if ( iid == IID_IInterface ) {
00210     *pinterface = (IInterface*)this;
00211   } 
00212   else {
00213     return StatusCode::FAILURE;
00214   }
00215   addRef();
00216   return StatusCode::SUCCESS;
00217 }
00218 
00219 
00220 
00221 

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