comparison Plugins/Engine/PluginsManager.cpp @ 888:d44b845c1c89 plugins

recursive scan for plugins
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 14 Jun 2014 19:47:51 +0200
parents 4066e6f2d134
children d2a393061eb6
comparison
equal deleted inserted replaced
887:4066e6f2d134 888:d44b845c1c89
33 #include "PluginsManager.h" 33 #include "PluginsManager.h"
34 34
35 #include <glog/logging.h> 35 #include <glog/logging.h>
36 #include <cassert> 36 #include <cassert>
37 #include <memory> 37 #include <memory>
38 #include <boost/filesystem.hpp>
39
40 #ifdef WIN32
41 #define PLUGIN_EXTENSION ".dll"
42 #elif defined(__linux)
43 #define PLUGIN_EXTENSION ".so"
44 #else
45 #error Support your platform here
46 #endif
47
38 48
39 namespace Orthanc 49 namespace Orthanc
40 { 50 {
41 static void CallInitialize(SharedLibrary& plugin, 51 static void CallInitialize(SharedLibrary& plugin,
42 const OrthancPluginContext& context) 52 const OrthancPluginContext& context)
77 87
78 finalize(); 88 finalize();
79 } 89 }
80 90
81 91
92 static const char* CallGetName(SharedLibrary& plugin)
93 {
94 typedef const char* (*GetName) ();
95
96 GetName getName;
97 *(void **) (&getName) = plugin.GetFunction("OrthancPluginGetName");
98 assert(getName != NULL);
99
100 return getName();
101 }
102
103
104 static const char* CallGetVersion(SharedLibrary& plugin)
105 {
106 typedef const char* (*GetVersion) ();
107
108 GetVersion getVersion;
109 *(void **) (&getVersion) = plugin.GetFunction("OrthancPluginGetVersion");
110 assert(getVersion != NULL);
111
112 return getVersion();
113 }
114
115
82 static void LogError(const char* str) 116 static void LogError(const char* str)
83 { 117 {
84 LOG(ERROR) << str; 118 LOG(ERROR) << str;
85 } 119 }
86 120
112 146
113 PluginsManager::~PluginsManager() 147 PluginsManager::~PluginsManager()
114 { 148 {
115 for (Plugins::iterator it = plugins_.begin(); it != plugins_.end(); it++) 149 for (Plugins::iterator it = plugins_.begin(); it != plugins_.end(); it++)
116 { 150 {
117 if (*it != NULL) 151 if (it->second != NULL)
118 { 152 {
119 CallFinalize(**it); 153 CallFinalize(*(it->second));
120 delete *it; 154 delete it->second;
121 } 155 }
122 } 156 }
157 }
158
159
160 static bool IsOrthancPlugin(SharedLibrary& library)
161 {
162 return (library.HasFunction("OrthancPluginInitialize") &&
163 library.HasFunction("OrthancPluginFinalize") &&
164 library.HasFunction("OrthancPluginGetName") &&
165 library.HasFunction("OrthancPluginGetVersion"));
123 } 166 }
124 167
125 168
126 void PluginsManager::RegisterPlugin(const std::string& path) 169 void PluginsManager::RegisterPlugin(const std::string& path)
127 { 170 {
128 std::auto_ptr<SharedLibrary> plugin(new SharedLibrary(path)); 171 std::auto_ptr<SharedLibrary> plugin(new SharedLibrary(path));
129 172
130 if (!plugin->HasFunction("OrthancPluginInitialize") || 173 if (!IsOrthancPlugin(*plugin))
131 !plugin->HasFunction("OrthancPluginFinalize"))
132 { 174 {
133 LOG(ERROR) << "Plugin " << plugin->GetPath() 175 LOG(ERROR) << "Plugin " << plugin->GetPath()
134 << " does not declare the proper entry functions"; 176 << " does not declare the proper entry functions";
135 throw OrthancException(ErrorCode_SharedLibrary); 177 throw OrthancException(ErrorCode_SharedLibrary);
136 } 178 }
137 179
138 LOG(WARNING) << "Registering plugin " << path; 180 std::string name(CallGetName(*plugin));
181 if (plugins_.find(name) != plugins_.end())
182 {
183 LOG(ERROR) << "Plugin '" << name << "' already registered";
184 throw OrthancException(ErrorCode_SharedLibrary);
185 }
186
187 LOG(WARNING) << "Registering plugin '" << name
188 << "' (version " << CallGetVersion(*plugin) << ")";
139 189
140 CallInitialize(*plugin, context_); 190 CallInitialize(*plugin, context_);
141 191
142 plugins_.push_back(plugin.release()); 192 plugins_[name] = plugin.release();
193 }
194
195
196 void PluginsManager::ScanFolderForPlugins(const std::string& path,
197 bool isRecursive)
198 {
199 using namespace boost::filesystem;
200
201 if (!exists(path))
202 {
203 return;
204 }
205
206 LOG(INFO) << "Scanning folder " << path << " for plugins";
207
208 directory_iterator end_it; // default construction yields past-the-end
209 for (directory_iterator it(path);
210 it != end_it;
211 ++it)
212 {
213 if (is_directory(it->status()))
214 {
215 if (isRecursive)
216 {
217 ScanFolderForPlugins(it->path().string(), true);
218 }
219 }
220 else
221 {
222 if (boost::filesystem::extension(it->path()) == PLUGIN_EXTENSION)
223 {
224 LOG(INFO) << "Found a shared library: " << it->path();
225
226 try
227 {
228 SharedLibrary plugin(it->path().string());
229 if (IsOrthancPlugin(plugin))
230 {
231 RegisterPlugin(it->path().string());
232 }
233 }
234 catch (OrthancException&)
235 {
236 }
237 }
238 }
239 }
143 } 240 }
144 241
145 } 242 }