Mercurial > hg > orthanc
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 } |