CEBL  2.1
PluginLoader.hpp
Go to the documentation of this file.
1 /*
2 * CEBL : CSU EEG Brain-Computer Interface Lab
3 *
4 * Author: Jeshua Bratman - jeshuabratman@gmail.com
5 *
6 * This file is part of CEBL.
7 *
8 * CEBL is free software; you can redistribute it and/or modify it.
9 * We only ask that if you use our code that you cite the source in
10 * your project or publication.
11 *
12 * EEG Group (www.cs.colostate.edu/eeg)
13 * Department of Computer Science
14 * Colorado State University
15 *
16 */
17 
18 
25 #ifndef PLUGINLOADER_H
26 #define PLUGINLOADER_H
27 
28 
29 #include "SharedLoader.hpp"
30 #include "Serialization.hpp"
31 #include "FileUtils.hpp"
32 #include "../Exceptions.hpp"
33 
34 
35 //std includes
36 #include <map>
37 #include <string>
38 #include <sstream>
39 #include <vector>
40 
41 //boost includes
42 #define BOOST_FILESYSTEM_VERSION 2
43 #include <boost/filesystem/operations.hpp>
44 #include <boost/filesystem/convenience.hpp>
45 #include <boost/filesystem/fstream.hpp>
46 #include <boost/filesystem/path.hpp>
47 
48 
49 //namespaces
50 using namespace std;
51 namespace fs = boost::filesystem;
52 
53 
54 template <typename T>
56 {
57 
58 private:
59  //list of shared loaders organized by filename
60  map<string, SharedLoader<T> > libs;
61  //list of instantiated plugins organized by filename
62  map<string, T* > plugins;
63  //list of paths associated with plugin filenames
64  map<string, string> paths;
65 
66 public:
68  ~PluginLoader();
69 
71  void loadDirs(std::vector<string> dirs) {
72  for(int i=0; i<dirs.size(); i++)
73  {
74  loadDir(dirs[i]);
75  }
76  };
78  void loadDir(string dir);
79 
80  //access loaded plugins
81  map<string, SharedLoader<T> > & getPluginsMap() { return libs; }
82  map<string, string > & getPathsMap() { return paths; }
83 
84  vector<SharedLoader<T> > & getPlugins();
85  vector<string> getPaths();
86  vector<string> getFileNames();
87  vector<string> getNames();
88  string getFilename(string plugin_name);
89 
90  string getPath(string lib);
91  string getPathByFilename(string lib);
92 
93  //gets shared loader for specified lib
94  SharedLoader<T> getLoader(string lib) { return libs[lib]; }
95 
96  //get copy of library for specified plugin name
97  T* getPlugin(string plugin);
98  //get copy of library for specified plugin filename
99  T* getPluginByFilename(string plugin);
100 
101 };
102 
103 //DESTRUCTOR
104 template <typename T>
106 {
107  typedef typename std::map<string, T* >::const_iterator mit; //required for templated iterators
108  for(mit it = plugins.begin(); it != plugins.end(); ++it)
109  {
110  if(it->second != NULL)
111  {
112  delete it->second;
113  }
114  }
115 }
116 
117 
118 //scans a directory for all shared libraries and loads them
119 template <typename T>
120 void PluginLoader<T>::loadDir(string directory)
121 {
122  fs::path full_path;
123  full_path = fs::system_complete(fs::path(directory, fs::native));
124 
125 
126  //make sure directory exists
127  if(!fs::exists(full_path))
128  {
129  throw FileException(string("Directory does not exist: ") + full_path.native_file_string());
130  }
131  //make sure it is a directory
132  if(!fs::is_directory(full_path))
133  {
134  throw FileException(full_path.native_file_string() + string(" is not a directory. "));
135  }
136 
137 
138  //loop through directory
139  fs::directory_iterator end_iter;
140  for (fs::directory_iterator dir_itr( full_path );
141  dir_itr != end_iter;
142  ++dir_itr )
143  {
144  try
145  {
146  string file = dir_itr->leaf();
147 
148  if(file.length() > 3)
149  {
150  if(file.substr(file.length()-3,3) == ".so")
151  {
152  string name = file.substr(0,file.length()-3);
153  string full_name = full_path.native_file_string() + file;
154  libs[name].LoadLibrary(full_name.c_str());
155  paths[name] = directory;
156  if(libs[name].Loaded())
157  {
158  cout << "Loaded plugin " << name << ".so" << endl;
159  plugins[name] = libs[name].New();
160  }
161  else
162  {
163  //remove entry
164  libs.erase(name);
165  }
166  }
167  }
168  }
169  catch(const std::exception & ex)
170  {
171  throw FileException("Failed to load shared libraries.");
172  }
173  }
174 
175 }
176 //get vectors of
177 template <typename T>
179 {
180  map<string, string>::iterator it;
181  vector<string> ret;
182  for(it=paths.begin(); it != paths.end(); ++it)
183  {
184 
185  ret.push_back(it->second);
186  }
187 
188  return ret;
189 
190 }
191 
192 template <typename T>
194 {
195  vector<string> ret;
196 
197  typedef typename std::map<string, SharedLoader<T> >::const_iterator mit; //required for templated iterators
198  for(mit it = libs.begin(); it != libs.end(); ++it)
199  {
200  ret.push_back(it->first);
201  }
202 
203  return ret;
204 
205 }
207 template <typename T>
209 {
210  vector<string> ret;
211 
212  typedef typename std::map<string, T* >::const_iterator mit; //required for templated iterators
213  for(mit it = plugins.begin(); it != plugins.end(); ++it)
214  {
215  ret.push_back(it->second->getName());
216  }
217 
218  return ret;
219 
220 }
221 
222 
223 
225 template <typename T>
226 string PluginLoader<T>::getFilename(string name)
227 {
228  typedef typename std::map<string, T* >::const_iterator mit; //required for templated iterators
229  for(mit it = plugins.begin(); it != plugins.end(); ++it)
230  {
231  if(it->second->getName() == name)
232  {
233  return it->first;
234  }
235  }
236  return "";
237 }
238 
239 
241 template <typename T>
243 {
244  if(plugins.count(name) > 0)
245  {
246  return plugins[name];
247  }
248  else
249  {
250  return NULL;
251  }
252 }
253 
254 
256 template <typename T>
258 {
259  if(paths.count(name) > 0)
260  {
261  return paths[name];
262  }
263  else
264  {
265  return "";
266  }
267 }
268 
270 template <typename T>
272 {
273  return getPluginByFilename(getFilename(name));
274 }
275 
277 template <typename T>
278 string PluginLoader<T>::getPath(string name)
279 {
280  return getPathByFilename(getFilename(name));
281 }
282 
283 #endif
284