1 #ifndef CORELIB___PLUGIN_MANAGER__IMPL__HPP 2 #define CORELIB___PLUGIN_MANAGER__IMPL__HPP 3 4 /* $Id: plugin_manager_impl.hpp 546046 2017-09-13 14:32:40Z sadyrovr $ 5 * =========================================================================== 6 * 7 * PUBLIC DOMAIN NOTICE 8 * National Center for Biotechnology Information 9 * 10 * This software/database is a "United States Government Work" under the 11 * terms of the United States Copyright Act. It was written as part of 12 * the author's official duties as a United States Government employee and 13 * thus cannot be copyrighted. This software/database is freely available 14 * to the public for use. The National Library of Medicine and the U.S. 15 * Government have not placed any restriction on its use or reproduction. 16 * 17 * Although all reasonable efforts have been taken to ensure the accuracy 18 * and reliability of the software and data, the NLM and the U.S. 19 * Government do not and cannot warrant the performance or results that 20 * may be obtained by using this software or data. The NLM and the U.S. 21 * Government disclaim all warranties, express or implied, including 22 * warranties of performance, merchantability or fitness for any particular 23 * purpose. 24 * 25 * Please cite the author in any work or product based on this material. 26 * 27 * =========================================================================== 28 * 29 * Author: Anatoliy Kuznetsov 30 * 31 * File Description: Collection of classes to implement different 32 * plugin manager paradigms. 33 * 34 * 35 */ 36 37 /// @file plugin_manager_impl.hpp 38 /// Helper classes and templates to implement plugins. 39 40 #include <corelib/plugin_manager.hpp> 41 42 43 BEGIN_NCBI_SCOPE 44 45 /** @addtogroup PluginMgr 46 * 47 * @{ 48 */ 49 50 51 /// Template class helps to implement one driver class factory. 52 /// 53 /// Class supports one driver, one version class factory 54 /// (the very basic one) 55 /// Template parameters are: 56 /// IFace - interface class 57 /// TDriver - driver class (implements IFace) 58 59 template <class IFace, class TDriver> 60 class CSimpleClassFactoryImpl : public IClassFactory<IFace> 61 { 62 public: 63 64 typedef TDriver TImplementation; 65 typedef IFace TInterface; 66 typedef IClassFactory<IFace> TParent; 67 typedef typename TParent::SDriverInfo TDriverInfo; 68 typedef typename TParent::TDriverList TDriverList; 69 70 /// Construction 71 /// 72 /// @param driver_name 73 /// Driver name string 74 /// @param patch_level 75 /// Patch level implemented by the driver. 76 /// By default corresponds to interface patch level. CSimpleClassFactoryImpl(const string & driver_name,int patch_level=-1)77 CSimpleClassFactoryImpl(const string& driver_name, int patch_level = -1) 78 : m_DriverVersionInfo 79 (TParent::GetDefaultDrvVers().GetMajor(), 80 TParent::GetDefaultDrvVers().GetMinor(), 81 patch_level >= 0 ? 82 patch_level : TParent::GetDefaultDrvVers().GetPatchLevel()), 83 m_DriverName(driver_name) 84 { 85 _ASSERT(!m_DriverName.empty()); 86 } 87 88 /// Create instance of TDriver 89 virtual TInterface* CreateInstance(const string & driver=kEmptyStr,CVersionInfo version=TParent::GetDefaultDrvVers (),const TPluginManagerParamTree * =0) const90 CreateInstance(const string& driver = kEmptyStr, 91 CVersionInfo version = TParent::GetDefaultDrvVers(), 92 const TPluginManagerParamTree* /*params*/ = 0) const 93 { 94 TDriver* drv = 0; 95 if (driver.empty() || driver == m_DriverName) { 96 if (version.Match(NCBI_INTERFACE_VERSION(IFace)) 97 != CVersionInfo::eNonCompatible) { 98 drv = new TImplementation(); 99 } 100 } 101 return drv; 102 } 103 GetDriverVersions(TDriverList & info_list) const104 void GetDriverVersions(TDriverList& info_list) const 105 { 106 info_list.push_back(TDriverInfo(m_DriverName, m_DriverVersionInfo)); 107 } 108 109 protected: 110 /// Utility function to get an element of parameter tree 111 /// Throws an exception when mandatory parameter is missing 112 /// (or returns the deafult value) GetParam(const TPluginManagerParamTree * params,const string & param_name,bool mandatory,const string & default_value) const113 string GetParam(const TPluginManagerParamTree* params, 114 const string& param_name, 115 bool mandatory, 116 const string& default_value) const 117 { 118 return 119 TParent::GetParam(m_DriverName, 120 params, param_name, mandatory, default_value); 121 } 122 123 /// This version always defaults to the empty string so that it 124 /// can safely return a reference. (default_value may be 125 /// temporary in some cases.) GetParam(const TPluginManagerParamTree * params,const string & param_name,bool mandatory) const126 const string& GetParam(const TPluginManagerParamTree* params, 127 const string& param_name, 128 bool mandatory) const 129 { 130 return 131 TParent::GetParam(m_DriverName, params, param_name, mandatory); 132 } 133 134 /// Utility function to get an integer of parameter tree 135 /// Throws an exception when mandatory parameter is missing 136 /// (or returns the deafult value) GetParamInt(const TPluginManagerParamTree * params,const string & param_name,bool,int default_value) const137 int GetParamInt(const TPluginManagerParamTree* params, 138 const string& param_name, 139 bool /* mandatory */, 140 int default_value) const 141 { 142 CConfig conf(params); 143 return conf.GetInt(m_DriverName, 144 param_name, 145 CConfig::eErr_NoThrow, 146 default_value); 147 } 148 149 /// Utility function to get an integer of parameter tree 150 /// Throws an exception when mandatory parameter is missing 151 /// (or returns the deafult value) 152 Uint8 GetParamDataSize(const TPluginManagerParamTree * params,const string & param_name,bool,unsigned int default_value) const153 GetParamDataSize(const TPluginManagerParamTree* params, 154 const string& param_name, 155 bool /* mandatory */, 156 unsigned int default_value) const 157 { 158 CConfig conf(params); 159 return conf.GetDataSize(m_DriverName, 160 param_name, 161 CConfig::eErr_NoThrow, 162 default_value); 163 } 164 165 166 /// Utility function to get an bool of parameter tree 167 /// Throws an exception when mandatory parameter is missing 168 /// (or returns the deafult value) GetParamBool(const TPluginManagerParamTree * params,const string & param_name,bool,bool default_value) const169 bool GetParamBool(const TPluginManagerParamTree* params, 170 const string& param_name, 171 bool /* mandatory */, 172 bool default_value) const 173 { 174 CConfig conf(params); 175 return conf.GetBool(m_DriverName, 176 param_name, 177 CConfig::eErr_NoThrow, 178 default_value); 179 180 } 181 182 183 /// Utility function to get a double of parameter tree 184 /// Throws an exception when mandatory parameter is missing 185 /// (or returns the default value) GetParamDouble(const TPluginManagerParamTree * params,const string & param_name,bool,double default_value) const186 double GetParamDouble(const TPluginManagerParamTree* params, 187 const string& param_name, 188 bool /* mandatory */, 189 double default_value) const 190 { 191 CConfig conf(params); 192 return conf.GetDouble(m_DriverName, 193 param_name, 194 CConfig::eErr_NoThrow, 195 default_value); 196 197 } 198 199 200 protected: 201 CVersionInfo m_DriverVersionInfo; 202 string m_DriverName; 203 }; 204 205 206 /// Template implements entry point 207 /// 208 /// The actual entry point is a C callable exported function 209 /// delegates the functionality to 210 /// CHostEntryPointImpl<>::NCBI_EntryPointImpl() 211 212 template<class TClassFactory> 213 struct CHostEntryPointImpl 214 { 215 typedef typename TClassFactory::TInterface TInterface; 216 typedef CPluginManager<TInterface> TPluginManager; 217 typedef typename CPluginManager<TInterface>::SDriverInfo TDriverInfo; 218 219 typedef typename 220 CPluginManager<TInterface>::TDriverInfoList TDriverInfoList; 221 typedef typename 222 CPluginManager<TInterface>::EEntryPointRequest EEntryPointRequest; 223 typedef typename TClassFactory::SDriverInfo TCFDriverInfo; 224 225 226 /// Entry point implementation. 227 /// 228 /// @sa CPluginManager::FNCBI_EntryPoint NCBI_EntryPointImplCHostEntryPointImpl229 static void NCBI_EntryPointImpl(TDriverInfoList& info_list, 230 EEntryPointRequest method) 231 { 232 TClassFactory cf; 233 list<TCFDriverInfo> cf_info_list; 234 cf.GetDriverVersions(cf_info_list); 235 236 switch (method) 237 { 238 case TPluginManager::eGetFactoryInfo: 239 { 240 typename list<TCFDriverInfo>::const_iterator it = 241 cf_info_list.begin(); 242 typename list<TCFDriverInfo>::const_iterator it_end = 243 cf_info_list.end(); 244 245 for (; it != it_end; ++it) { 246 info_list.push_back(TDriverInfo(it->name, it->version)); 247 } 248 249 } 250 break; 251 case TPluginManager::eInstantiateFactory: 252 { 253 typename TDriverInfoList::iterator it1 = info_list.begin(); 254 typename TDriverInfoList::iterator it1_end = info_list.end(); 255 for(; it1 != it1_end; ++it1) { 256 // We do only an exact match here. 257 // A factory cannot be matched twice. 258 _ASSERT( it1->factory == NULL ); 259 260 typename list<TCFDriverInfo>::iterator it2 = 261 cf_info_list.begin(); 262 typename list<TCFDriverInfo>::iterator it2_end = 263 cf_info_list.end(); 264 265 for (; it2 != it2_end; ++it2) { 266 if (it1->name == it2->name) { 267 // We do only an exact match here. 268 if (it1->version.Match(it2->version) == 269 CVersionInfo::eFullyCompatible) 270 { 271 _ASSERT( it1->factory == NULL ); 272 273 TClassFactory* cg = new TClassFactory(); 274 IClassFactory<TInterface>* icf = cg; 275 it1->factory = icf; 276 } 277 } 278 } // for 279 280 } // for 281 282 } 283 break; 284 default: 285 _ASSERT(0); 286 } // switch 287 } 288 289 }; 290 291 292 /* @} */ 293 294 END_NCBI_SCOPE 295 296 #endif /* CORELIB___PLUGIN_MANAGER__IMPL_HPP */ 297