All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
WarePluginsManager.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2007, INRA - Montpellier SupAgro
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30 */
31 
32 
33 /**
34  \file WarePluginsManager.hpp
35  \brief Header of ...
36 
37  \author Jean-Christophe FABRE <fabrejc@supagro.inra.fr>
38  */
39 
40 
41 #ifndef __WAREPLUGINSMANAGER_HPP__
42 #define __WAREPLUGINSMANAGER_HPP__
43 
44 #include <vector>
45 #include <map>
46 #include <string>
47 
48 #include <QLibrary>
49 #include <QFileInfo>
50 
52 #include <openfluid/dllexport.hpp>
53 #include <openfluid/config.hpp>
54 
55 
56 namespace openfluid { namespace machine {
57 
58 
59 typedef std::string (*GetWareABIVersionProc)();
60 
61 
62 // =====================================================================
63 // =====================================================================
64 
65 
66 /**
67  Management class for pluggable ware
68  @tparam S class defining the container for ware signature only
69  @tparam M class defining the container for ware signature and body
70  @tparam SP procedure definition for instantiation of the signature
71  @tparam BP procedure definition for instantiation of the body
72 */
73 template<class S, class M, typename SP, typename BP>
75 {
76  private:
77 
78  QLibrary* loadWare(const std::string& FullFilePath)
79  {
80  std::string PluginFileName = QFileInfo(QString::fromStdString(FullFilePath)).fileName().toStdString();
81 
82  if (m_LoadedPlugins.find(PluginFileName) == m_LoadedPlugins.end())
83  {
84  m_LoadedPlugins[PluginFileName] = new QLibrary(QString::fromStdString(FullFilePath));
85  }
86 
87  return m_LoadedPlugins[PluginFileName];
88  }
89 
90 
91  // =====================================================================
92  // =====================================================================
93 
94 
95  M* buildWareContainerWithSignatureOnly(const std::string& ID)
96  {
97 
98  std::string PluginFilename = ID+getPluginFilenameSuffix()+openfluid::config::PLUGINS_EXT;
99  std::string PluginFullPath = getPluginFullPath(PluginFilename);
100  M* Plug = NULL;
101 
102  QLibrary* PlugLib = loadWare(PluginFullPath);
103 
104  // library loading
105  if (PlugLib)
106  {
107  Plug = new M();
108  Plug->FileFullPath = PluginFullPath;
109 
110  GetWareABIVersionProc ABIVersionProc = (GetWareABIVersionProc)PlugLib->resolve(WAREABIVERSION_PROC_NAME);
111 
112  if (ABIVersionProc)
113  {
114  Plug->Verified = (openfluid::tools::CompareVersions(openfluid::config::FULL_VERSION,ABIVersionProc(),false) == 0);
115  }
116  else Plug->Verified = false;
117 
118 
119  if (Plug->Verified)
120  {
121  BP BodyProc = (BP)PlugLib->resolve(WAREBODY_PROC_NAME);
122  SP SignatureProc = (SP)PlugLib->resolve(WARESIGNATURE_PROC_NAME);
123 
124  // checks if the handle procs exist
125  if (SignatureProc && BodyProc)
126  {
127  Plug->Signature = SignatureProc();
128 
129  if (Plug->Signature == NULL)
130  throw openfluid::base::FrameworkException("WarePluginsManager::buildWareContainerWithSignatureOnly","Signature from plugin file " + PluginFilename + " cannot be instanciated");
131 
132  Plug->Verified = (Plug->Signature->ID == ID);
133 
134  Plug->Body = 0;
135  }
136  else throw openfluid::base::FrameworkException("WarePluginsManager::buildWareContainerWithSignatureOnly","Format error in plugin file " + PluginFilename);
137  }
138  else throw openfluid::base::FrameworkException("WarePluginsManager::buildWareContainerWithSignatureOnly","Compatibility version mismatch for plugin file " + PluginFilename);
139  }
140  else throw openfluid::base::FrameworkException("WarePluginsManager::buildWareContainerWithSignatureOnly","Unable to load plugin from file " + PluginFilename);
141 
142  return Plug;
143  }
144 
145 
146  // =====================================================================
147  // =====================================================================
148 
149 
150  S* getWareSignature(const std::string& PluginFilename)
151  {
152  std::string PluginFullPath = getPluginFullPath(PluginFilename);
153  S* Plug = NULL;
154 
155  QLibrary* PlugLib = loadWare(PluginFullPath);
156 
157  // library loading
158  if (PlugLib)
159  {
160  Plug = new M();
161  Plug->FileFullPath = PluginFullPath;
162 
163  GetWareABIVersionProc ABIVersionProc = (GetWareABIVersionProc)PlugLib->resolve(WAREABIVERSION_PROC_NAME);
164 
165  if (ABIVersionProc)
166  {
167  Plug->Verified = (openfluid::tools::CompareVersions(openfluid::config::FULL_VERSION,ABIVersionProc(),false) == 0);
168  }
169  else Plug->Verified = false;
170 
171 
172  if (Plug->Verified)
173  {
174  BP BodyProc = (BP)PlugLib->resolve(WAREBODY_PROC_NAME);
175  SP SignatureProc = (SP)PlugLib->resolve(WARESIGNATURE_PROC_NAME);
176 
177  // checks if the handle procs exist
178  if (SignatureProc && BodyProc)
179  {
180  Plug->Signature = SignatureProc();
181 
182  if (Plug->Signature == NULL)
183  throw openfluid::base::FrameworkException("WarePluginsManager::getWareSignature","Signature from plugin file " + PluginFilename + " cannot be instanciated");
184 
185  Plug->Verified = QString::fromStdString(PluginFilename).startsWith(QString::fromStdString(Plug->Signature->ID));
186  }
187  else throw openfluid::base::FrameworkException("WarePluginsManager::getWareSignature","Format error in plugin file " + PluginFilename);
188  }
189  }
190  else throw openfluid::base::FrameworkException("WarePluginsManager::getWareSignature","Unable to find plugin file " + PluginFilename);
191 
192  return Plug;
193  }
194 
195 
196  // =====================================================================
197  // =====================================================================
198 
199 
200  protected:
201 
202  std::map<std::string,QLibrary*> m_LoadedPlugins;
203 
204 
206  {
207 
208  }
209 
210 
211  // =====================================================================
212  // =====================================================================
213 
214 
215  public:
216 
218  {
219 
220  }
221 
222 
223  // =====================================================================
224  // =====================================================================
225 
226 
227  virtual std::string getPluginFullPath(const std::string& Filename) = 0;
228 
229 
230  // =====================================================================
231  // =====================================================================
232 
233 
234  virtual std::vector<std::string> getPluginsSearchPaths() = 0;
235 
236 
237  // =====================================================================
238  // =====================================================================
239 
240 
241  virtual std::string getPluginFilenameSuffix() = 0;
242 
243 
244  // =====================================================================
245  // =====================================================================
246 
247 
248  /**
249  Lists available wares
250  */
251  std::vector<S*> getAvailableWaresSignatures(const std::string Pattern = "")
252  {
253  std::vector<S*> PluginsContainers;
254  std::vector<std::string> PluginsPaths = getPluginsSearchPaths();
255  std::vector<std::string> PluginFiles;
256  std::vector<std::string> TmpFiles;
257  unsigned int i,j;
258 
259 
260  for (i=0;i<PluginsPaths.size();i++)
261  {
262  TmpFiles = openfluid::tools::GetFilesBySuffixAndExt(PluginsPaths[i],getPluginFilenameSuffix(),openfluid::config::PLUGINS_EXT,false,true);
263  for (j=0;j<TmpFiles.size();j++) PluginFiles.push_back(TmpFiles[j]);
264  }
265 
266 
267  S* CurrentPlug;
268 
269  for (i=0;i<PluginFiles.size();i++)
270  {
271  CurrentPlug = getWareSignature(PluginFiles[i]);
272 
273  if (CurrentPlug != NULL && CurrentPlug->Verified)
274  {
275  if (Pattern != "")
276  {
277  if (openfluid::tools::WildcardMatching(Pattern,CurrentPlug->Signature->ID))
278  PluginsContainers.push_back(CurrentPlug);
279  }
280  else PluginsContainers.push_back(CurrentPlug);
281  }
282  }
283 
284  return PluginsContainers;
285  }
286 
287 
288  // =====================================================================
289  // =====================================================================
290 
291 
292  M* loadWareSignatureOnly(const std::string& ID)
293  {
294  M* Plug = buildWareContainerWithSignatureOnly(ID);
295 
296  if (Plug != NULL && Plug->Verified) return Plug;
297 
298  return NULL;
299  }
300 
301 
302  // =====================================================================
303  // =====================================================================
304 
305 
307  {
308  std::string PluginFullPath = Item->FileFullPath;
309 
310  QLibrary* PlugLib = loadWare(PluginFullPath);
311 
312  // library loading
313  if (PlugLib)
314  {
315  BP BodyProc = (BP)PlugLib->resolve(WAREBODY_PROC_NAME);
316 
317  // checks if the handle proc exists
318  if(BodyProc)
319  {
320  Item->Body = BodyProc();
321 
322  if (Item->Body == NULL)
323  throw openfluid::base::FrameworkException("WarePluginsManager::completeSignatureWithWareBody","Ware from plugin file " + PluginFullPath + " cannot be instanciated");
324 
325  }
326  else throw openfluid::base::FrameworkException("completeSignatureWithWareBody","Format error in plugin file " + PluginFullPath);
327  }
328  else throw openfluid::base::FrameworkException("completeSignatureWithWareBody","Unable to find plugin file " + PluginFullPath);
329  }
330 
331 
332  // =====================================================================
333  // =====================================================================
334 
335 
337  {
338  std::map<std::string,QLibrary*>::iterator it;
339 
340  for (it=m_LoadedPlugins.begin();it != m_LoadedPlugins.end(); ++it)
341  {
342  it->second->unload();
343  delete (it->second);
344  }
345 
346  m_LoadedPlugins.clear();
347  }
348 
349 };
350 
351 
352 
353 } } //namespaces
354 
355 
356 
357 
358 #endif /* __WAREPLUGINSMANAGER_HPP__ */
int DLLEXPORT CompareVersions(const std::string &VersionA, const std::string &VersionB, bool Strict=true)
#define WAREABIVERSION_PROC_NAME
Definition: PluggableWare.hpp:71
std::map< std::string, QLibrary * > m_LoadedPlugins
Definition: WarePluginsManager.hpp:202
void completeSignatureWithWareBody(M *Item)
Definition: WarePluginsManager.hpp:306
Definition: FrameworkException.hpp:49
virtual ~WarePluginsManager()
Definition: WarePluginsManager.hpp:217
void unloadAllWares()
Definition: WarePluginsManager.hpp:336
std::string(* GetWareABIVersionProc)()
Definition: WarePluginsManager.hpp:59
#define WARESIGNATURE_PROC_NAME
Definition: PluggableWare.hpp:65
std::vector< std::string > DLLEXPORT GetFilesBySuffixAndExt(const std::string &DirToExplore, const std::string &Suffix, const std::string &Ext, bool WithPath=false, bool ExtIncludeDot=false)
bool DLLEXPORT WildcardMatching(const std::string &Pattern, const std::string &Str)
std::vector< S * > getAvailableWaresSignatures(const std::string Pattern="")
Definition: WarePluginsManager.hpp:251
WarePluginsManager()
Definition: WarePluginsManager.hpp:205
Definition: WarePluginsManager.hpp:74
M * loadWareSignatureOnly(const std::string &ID)
Definition: WarePluginsManager.hpp:292
Header of ...
#define WAREBODY_PROC_NAME
Definition: PluggableWare.hpp:59
#define DLLEXPORT
Definition: dllexport.hpp:51