Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef __WAREPLUGINSMANAGER_HPP__
00042 #define __WAREPLUGINSMANAGER_HPP__
00043
00044 #include <vector>
00045 #include <map>
00046 #include <string>
00047
00048 #include <QLibrary>
00049 #include <QFileInfo>
00050
00051 #include <openfluid/ware/PluggableWare.hpp>
00052 #include <openfluid/dllexport.hpp>
00053 #include <openfluid/config.hpp>
00054
00055
00056 namespace openfluid { namespace machine {
00057
00058
00059 typedef std::string (*GetWareABIVersionProc)();
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 template<class S, class M, typename SP, typename BP>
00074 class DLLEXPORT WarePluginsManager
00075 {
00076 private:
00077
00078 QLibrary* loadWare(const std::string& FullFilePath)
00079 {
00080 std::string PluginFileName = QFileInfo(QString::fromStdString(FullFilePath)).fileName().toStdString();
00081
00082 if (m_LoadedPlugins.find(PluginFileName) == m_LoadedPlugins.end())
00083 {
00084 m_LoadedPlugins[PluginFileName] = new QLibrary(QString::fromStdString(FullFilePath));
00085 }
00086
00087 return m_LoadedPlugins[PluginFileName];
00088 }
00089
00090
00091
00092
00093
00094
00095 M* buildWareContainerWithSignatureOnly(const std::string& ID)
00096 {
00097
00098 std::string PluginFilename = ID+getPluginFilenameSuffix()+openfluid::config::PLUGINS_EXT;
00099 std::string PluginFullPath = getPluginFullPath(PluginFilename);
00100 M* Plug = NULL;
00101
00102 QLibrary* PlugLib = loadWare(PluginFullPath);
00103
00104
00105 if (PlugLib)
00106 {
00107 Plug = new M();
00108 Plug->FileFullPath = PluginFullPath;
00109
00110 GetWareABIVersionProc ABIVersionProc = (GetWareABIVersionProc)PlugLib->resolve(WAREABIVERSION_PROC_NAME);
00111
00112 if (ABIVersionProc)
00113 {
00114 Plug->Verified = (openfluid::tools::CompareVersions(openfluid::config::FULL_VERSION,ABIVersionProc(),false) == 0);
00115 }
00116 else Plug->Verified = false;
00117
00118
00119 if (Plug->Verified)
00120 {
00121 BP BodyProc = (BP)PlugLib->resolve(WAREBODY_PROC_NAME);
00122 SP SignatureProc = (SP)PlugLib->resolve(WARESIGNATURE_PROC_NAME);
00123
00124
00125 if (SignatureProc && BodyProc)
00126 {
00127 Plug->Signature = SignatureProc();
00128
00129 if (Plug->Signature == NULL)
00130 throw openfluid::base::FrameworkException("WarePluginsManager::buildWareContainerWithSignatureOnly","Signature from plugin file " + PluginFilename + " cannot be instanciated");
00131
00132 Plug->Verified = (Plug->Signature->ID == ID);
00133
00134 Plug->Body = 0;
00135 }
00136 else throw openfluid::base::FrameworkException("WarePluginsManager::buildWareContainerWithSignatureOnly","Format error in plugin file " + PluginFilename);
00137 }
00138 else throw openfluid::base::FrameworkException("WarePluginsManager::buildWareContainerWithSignatureOnly","Compatibility version mismatch for plugin file " + PluginFilename);
00139 }
00140 else throw openfluid::base::FrameworkException("WarePluginsManager::buildWareContainerWithSignatureOnly","Unable to load plugin from file " + PluginFilename);
00141
00142 return Plug;
00143 }
00144
00145
00146
00147
00148
00149
00150 S* getWareSignature(const std::string& PluginFilename)
00151 {
00152 std::string PluginFullPath = getPluginFullPath(PluginFilename);
00153 S* Plug = NULL;
00154
00155 QLibrary* PlugLib = loadWare(PluginFullPath);
00156
00157
00158 if (PlugLib)
00159 {
00160 Plug = new M();
00161 Plug->FileFullPath = PluginFullPath;
00162
00163 GetWareABIVersionProc ABIVersionProc = (GetWareABIVersionProc)PlugLib->resolve(WAREABIVERSION_PROC_NAME);
00164
00165 if (ABIVersionProc)
00166 {
00167 Plug->Verified = (openfluid::tools::CompareVersions(openfluid::config::FULL_VERSION,ABIVersionProc(),false) == 0);
00168 }
00169 else Plug->Verified = false;
00170
00171
00172 if (Plug->Verified)
00173 {
00174 BP BodyProc = (BP)PlugLib->resolve(WAREBODY_PROC_NAME);
00175 SP SignatureProc = (SP)PlugLib->resolve(WARESIGNATURE_PROC_NAME);
00176
00177
00178 if (SignatureProc && BodyProc)
00179 {
00180 Plug->Signature = SignatureProc();
00181
00182 if (Plug->Signature == NULL)
00183 throw openfluid::base::FrameworkException("WarePluginsManager::getWareSignature","Signature from plugin file " + PluginFilename + " cannot be instanciated");
00184
00185 Plug->Verified = QString::fromStdString(PluginFilename).startsWith(QString::fromStdString(Plug->Signature->ID));
00186 }
00187 else throw openfluid::base::FrameworkException("WarePluginsManager::getWareSignature","Format error in plugin file " + PluginFilename);
00188 }
00189 }
00190 else throw openfluid::base::FrameworkException("WarePluginsManager::getWareSignature","Unable to find plugin file " + PluginFilename);
00191
00192 return Plug;
00193 }
00194
00195
00196
00197
00198
00199
00200 protected:
00201
00202 std::map<std::string,QLibrary*> m_LoadedPlugins;
00203
00204
00205 WarePluginsManager()
00206 {
00207
00208 }
00209
00210
00211
00212
00213
00214
00215 public:
00216
00217 virtual ~WarePluginsManager()
00218 {
00219
00220 }
00221
00222
00223
00224
00225
00226
00227 virtual std::string getPluginFullPath(const std::string& Filename) = 0;
00228
00229
00230
00231
00232
00233
00234 virtual std::vector<std::string> getPluginsSearchPaths() = 0;
00235
00236
00237
00238
00239
00240
00241 virtual std::string getPluginFilenameSuffix() = 0;
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 std::vector<S*> getAvailableWaresSignatures(const std::string Pattern = "")
00252 {
00253 std::vector<S*> PluginsContainers;
00254 std::vector<std::string> PluginsPaths = getPluginsSearchPaths();
00255 std::vector<std::string> PluginFiles;
00256 std::vector<std::string> TmpFiles;
00257 unsigned int i,j;
00258
00259
00260 for (i=0;i<PluginsPaths.size();i++)
00261 {
00262 TmpFiles = openfluid::tools::GetFilesBySuffixAndExt(PluginsPaths[i],getPluginFilenameSuffix(),openfluid::config::PLUGINS_EXT,false,true);
00263 for (j=0;j<TmpFiles.size();j++) PluginFiles.push_back(TmpFiles[j]);
00264 }
00265
00266
00267 S* CurrentPlug;
00268
00269 for (i=0;i<PluginFiles.size();i++)
00270 {
00271 CurrentPlug = getWareSignature(PluginFiles[i]);
00272
00273 if (CurrentPlug != NULL && CurrentPlug->Verified)
00274 {
00275 if (Pattern != "")
00276 {
00277 if (openfluid::tools::WildcardMatching(Pattern,CurrentPlug->Signature->ID))
00278 PluginsContainers.push_back(CurrentPlug);
00279 }
00280 else PluginsContainers.push_back(CurrentPlug);
00281 }
00282 }
00283
00284 return PluginsContainers;
00285 }
00286
00287
00288
00289
00290
00291
00292 M* loadWareSignatureOnly(const std::string& ID)
00293 {
00294 M* Plug = buildWareContainerWithSignatureOnly(ID);
00295
00296 if (Plug != NULL && Plug->Verified) return Plug;
00297
00298 return NULL;
00299 }
00300
00301
00302
00303
00304
00305
00306 void completeSignatureWithWareBody(M* Item)
00307 {
00308 std::string PluginFullPath = Item->FileFullPath;
00309
00310 QLibrary* PlugLib = loadWare(PluginFullPath);
00311
00312
00313 if (PlugLib)
00314 {
00315 BP BodyProc = (BP)PlugLib->resolve(WAREBODY_PROC_NAME);
00316
00317
00318 if(BodyProc)
00319 {
00320 Item->Body = BodyProc();
00321
00322 if (Item->Body == NULL)
00323 throw openfluid::base::FrameworkException("WarePluginsManager::completeSignatureWithWareBody","Ware from plugin file " + PluginFullPath + " cannot be instanciated");
00324
00325 }
00326 else throw openfluid::base::FrameworkException("completeSignatureWithWareBody","Format error in plugin file " + PluginFullPath);
00327 }
00328 else throw openfluid::base::FrameworkException("completeSignatureWithWareBody","Unable to find plugin file " + PluginFullPath);
00329 }
00330
00331
00332
00333
00334
00335
00336 void unloadAllWares()
00337 {
00338 std::map<std::string,QLibrary*>::iterator it;
00339
00340 for (it=m_LoadedPlugins.begin();it != m_LoadedPlugins.end(); ++it)
00341 {
00342 it->second->unload();
00343 delete (it->second);
00344 }
00345
00346 m_LoadedPlugins.clear();
00347 }
00348
00349 };
00350
00351
00352
00353 } }
00354
00355
00356
00357
00358 #endif