# HG changeset patch # User Sebastien Jodogne # Date 1442834805 -7200 # Node ID ffd23c0104af9b12620f8ad04bd503a69c38184b # Parent bad4772b605c2748360d07447bbc599e85366b4e "/system" URI gives information about the plugins used for storage area and DB back-end diff -r bad4772b605c -r ffd23c0104af Core/Enumerations.cpp --- a/Core/Enumerations.cpp Fri Sep 18 17:45:59 2015 +0200 +++ b/Core/Enumerations.cpp Mon Sep 21 13:26:45 2015 +0200 @@ -298,6 +298,15 @@ case ErrorCode_LuaReturnsNoString: return "The Lua function does not return a string"; + case ErrorCode_StorageAreaAlreadyRegistered: + return "Another plugin has already registered a custom storage area"; + + case ErrorCode_DatabaseBackendAlreadyRegistered: + return "Another plugin has already registered a custom database back-end"; + + case ErrorCode_DatabasePlugin: + return "The plugin implementing a custom database back-end does not fulfill the proper interface"; + default: return "Unknown error code"; } diff -r bad4772b605c -r ffd23c0104af Core/Enumerations.h --- a/Core/Enumerations.h Fri Sep 18 17:45:59 2015 +0200 +++ b/Core/Enumerations.h Mon Sep 21 13:26:45 2015 +0200 @@ -128,7 +128,10 @@ ErrorCode_LuaAlreadyExecuted = 2032 /*!< Arguments cannot be pushed after the Lua function is executed */, ErrorCode_LuaBadOutput = 2033 /*!< The Lua function does not give the expected number of outputs */, ErrorCode_NotLuaPredicate = 2034 /*!< The Lua function is not a predicate (only true/false outputs allowed) */, - ErrorCode_LuaReturnsNoString = 2035 /*!< The Lua function does not return a string */ + ErrorCode_LuaReturnsNoString = 2035 /*!< The Lua function does not return a string */, + ErrorCode_StorageAreaAlreadyRegistered = 2036 /*!< Another plugin has already registered a custom storage area */, + ErrorCode_DatabaseBackendAlreadyRegistered = 2037 /*!< Another plugin has already registered a custom database back-end */, + ErrorCode_DatabasePlugin = 2038 /*!< The plugin implementing a custom database back-end does not fulfill the proper interface */ }; enum LogLevel diff -r bad4772b605c -r ffd23c0104af NEWS --- a/NEWS Fri Sep 18 17:45:59 2015 +0200 +++ b/NEWS Mon Sep 21 13:26:45 2015 +0200 @@ -6,6 +6,7 @@ Maintenance ----------- +* "/system" URI gives information about the plugins used for storage area and DB back-end * Plugin callbacks must now return explicit "OrthancPluginErrorCode" instead of integers diff -r bad4772b605c -r ffd23c0104af OrthancServer/OrthancRestApi/OrthancRestSystem.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp Fri Sep 18 17:45:59 2015 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp Mon Sep 21 13:26:45 2015 +0200 @@ -62,6 +62,21 @@ result["Name"] = Configuration::GetGlobalStringParameter("Name", ""); result["Version"] = ORTHANC_VERSION; + result["StorageAreaPlugin"] = Json::nullValue; + result["DatabaseBackendPlugin"] = Json::nullValue; + + const OrthancPlugins& plugins = OrthancRestApi::GetContext(call).GetPlugins(); + + if (plugins.HasStorageArea()) + { + result["StorageAreaPlugin"] = plugins.GetStorageAreaLibrary().GetPath(); + } + + if (plugins.HasDatabaseBackend()) + { + result["DatabaseBackendPlugin"] = plugins.GetDatabaseBackendLibrary().GetPath(); + } + call.GetOutput().AnswerJson(result); } diff -r bad4772b605c -r ffd23c0104af OrthancServer/main.cpp --- a/OrthancServer/main.cpp Fri Sep 18 17:45:59 2015 +0200 +++ b/OrthancServer/main.cpp Mon Sep 21 13:26:45 2015 +0200 @@ -624,10 +624,10 @@ LoadPlugins(plugins); IDatabaseWrapper* database = NULL; - if (plugins.HasDatabase()) + if (plugins.HasDatabaseBackend()) { LOG(WARNING) << "Using a custom database from plugins"; - database = &plugins.GetDatabase(); + database = &plugins.GetDatabaseBackend(); } else { diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/IPluginServiceProvider.h --- a/Plugins/Engine/IPluginServiceProvider.h Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/IPluginServiceProvider.h Mon Sep 21 13:26:45 2015 +0200 @@ -34,7 +34,7 @@ #include "../Include/orthanc/OrthancCPlugin.h" -#include +#include "SharedLibrary.h" namespace Orthanc { @@ -45,7 +45,8 @@ { } - virtual bool InvokeService(_OrthancPluginService service, + virtual bool InvokeService(SharedLibrary& plugin, + _OrthancPluginService service, const void* parameters) = 0; }; } diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/OrthancPluginDatabase.cpp --- a/Plugins/Engine/OrthancPluginDatabase.cpp Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/OrthancPluginDatabase.cpp Mon Sep 21 13:26:45 2015 +0200 @@ -113,7 +113,7 @@ if (type_ != _OrthancPluginDatabaseAnswerType_None && type_ != _OrthancPluginDatabaseAnswerType_Int64) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } target.clear(); @@ -134,7 +134,7 @@ if (type_ != _OrthancPluginDatabaseAnswerType_None && type_ != _OrthancPluginDatabaseAnswerType_String) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } target.clear(); @@ -164,7 +164,7 @@ } else { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } } @@ -183,15 +183,17 @@ } else { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } } - OrthancPluginDatabase::OrthancPluginDatabase(const OrthancPluginDatabaseBackend& backend, + OrthancPluginDatabase::OrthancPluginDatabase(SharedLibrary& library, + const OrthancPluginDatabaseBackend& backend, const OrthancPluginDatabaseExtensions* extensions, size_t extensionsSize, void *payload) : + library_(library), type_(_OrthancPluginDatabaseAnswerType_None), backend_(backend), payload_(payload), @@ -333,7 +335,7 @@ std::string value; if (!LookupMetadata(value, id, *it)) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } target[*it] = value; @@ -544,7 +546,7 @@ if (!ForwardSingleAnswer(s)) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } return s; @@ -656,7 +658,7 @@ if (type_ != _OrthancPluginDatabaseAnswerType_None && type_ != _OrthancPluginDatabaseAnswerType_Int32) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } target.clear(); @@ -687,7 +689,7 @@ if (type_ != _OrthancPluginDatabaseAnswerType_None && type_ != _OrthancPluginDatabaseAnswerType_Int32) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } target.clear(); @@ -770,7 +772,7 @@ } else { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } } @@ -889,7 +891,7 @@ } else { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } } @@ -1072,7 +1074,7 @@ } default: - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } } @@ -1122,7 +1124,7 @@ { if (answer.type == _OrthancPluginDatabaseAnswerType_None) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } if (answer.type == _OrthancPluginDatabaseAnswerType_DeletedAttachment || @@ -1177,13 +1179,13 @@ default: LOG(ERROR) << "Unhandled type of answer for custom index plugin: " << answer.type; - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } } else if (type_ != answer.type) { LOG(ERROR) << "Error in the plugin protocol: Cannot change the answer type"; - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } switch (answer.type) @@ -1228,7 +1230,7 @@ { if (answer.valueString == NULL) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } if (type_ == _OrthancPluginDatabaseAnswerType_None) @@ -1238,7 +1240,7 @@ } else if (type_ != _OrthancPluginDatabaseAnswerType_String) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } answerStrings_.push_back(std::string(answer.valueString)); @@ -1254,7 +1256,7 @@ } else if (*answerDone_) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } else { @@ -1280,7 +1282,7 @@ } else if (*answerDone_) { - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } else { @@ -1304,7 +1306,7 @@ default: LOG(ERROR) << "Unhandled type of answer for custom index plugin: " << answer.type; - throw OrthancException(ErrorCode_Plugin); + throw OrthancException(ErrorCode_DatabasePlugin); } } } diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/OrthancPluginDatabase.h --- a/Plugins/Engine/OrthancPluginDatabase.h Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/OrthancPluginDatabase.h Mon Sep 21 13:26:45 2015 +0200 @@ -34,6 +34,7 @@ #include "../../OrthancServer/IDatabaseWrapper.h" #include "../Include/orthanc/OrthancCDatabasePlugin.h" +#include "SharedLibrary.h" namespace Orthanc { @@ -44,6 +45,7 @@ typedef std::pair AnswerResource; + SharedLibrary& library_; _OrthancPluginDatabaseAnswerType type_; OrthancPluginDatabaseBackend backend_; OrthancPluginDatabaseExtensions extensions_; @@ -77,11 +79,17 @@ bool ForwardSingleAnswer(int64_t& target); public: - OrthancPluginDatabase(const OrthancPluginDatabaseBackend& backend, + OrthancPluginDatabase(SharedLibrary& library, + const OrthancPluginDatabaseBackend& backend, const OrthancPluginDatabaseExtensions* extensions, size_t extensionsSize, void *payload); + const SharedLibrary& GetSharedLibrary() const + { + return library_; + } + virtual void AddAttachment(int64_t id, const FileInfo& attachment); diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/OrthancPlugins.cpp --- a/Plugins/Engine/OrthancPlugins.cpp Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Mon Sep 21 13:26:45 2015 +0200 @@ -55,6 +55,117 @@ namespace Orthanc { + namespace + { + class PluginStorageArea : public IStorageArea + { + private: + _OrthancPluginRegisterStorageArea callbacks_; + + void Free(void* buffer) const + { + if (buffer != NULL) + { + callbacks_.free(buffer); + } + } + + public: + PluginStorageArea(const _OrthancPluginRegisterStorageArea& callbacks) : callbacks_(callbacks) + { + } + + + virtual void Create(const std::string& uuid, + const void* content, + size_t size, + FileContentType type) + { + OrthancPluginErrorCode error = callbacks_.create + (uuid.c_str(), content, size, Plugins::Convert(type)); + + if (error != OrthancPluginErrorCode_Success) + { + throw OrthancException(Plugins::Convert(error)); + } + } + + + virtual void Read(std::string& content, + const std::string& uuid, + FileContentType type) + { + void* buffer = NULL; + int64_t size = 0; + + OrthancPluginErrorCode error = callbacks_.read + (&buffer, &size, uuid.c_str(), Plugins::Convert(type)); + + if (error != OrthancPluginErrorCode_Success) + { + throw OrthancException(Plugins::Convert(error)); + } + + try + { + content.resize(static_cast(size)); + } + catch (...) + { + Free(buffer); + throw; + } + + if (size > 0) + { + memcpy(&content[0], buffer, static_cast(size)); + } + + Free(buffer); + } + + + virtual void Remove(const std::string& uuid, + FileContentType type) + { + OrthancPluginErrorCode error = callbacks_.remove + (uuid.c_str(), Plugins::Convert(type)); + + if (error != OrthancPluginErrorCode_Success) + { + throw OrthancException(Plugins::Convert(error)); + } + } + }; + + + class StorageAreaFactory : public boost::noncopyable + { + private: + SharedLibrary& sharedLibrary_; + _OrthancPluginRegisterStorageArea callbacks_; + + public: + StorageAreaFactory(SharedLibrary& sharedLibrary, + const _OrthancPluginRegisterStorageArea& callbacks) : + sharedLibrary_(sharedLibrary), + callbacks_(callbacks) + { + } + + SharedLibrary& GetSharedLibrary() + { + return sharedLibrary_; + } + + IStorageArea* Create() const + { + return new PluginStorageArea(callbacks_); + } + }; + } + + struct OrthancPlugins::PImpl { class RestCallback : public boost::noncopyable @@ -105,6 +216,7 @@ } }; + typedef std::pair Property; typedef std::list RestCallbacks; typedef std::list OnStoredCallbacks; @@ -116,8 +228,7 @@ RestCallbacks restCallbacks_; OnStoredCallbacks onStoredCallbacks_; OnChangeCallbacks onChangeCallbacks_; - bool hasStorageArea_; - _OrthancPluginRegisterStorageArea storageArea_; + std::auto_ptr storageArea_; boost::recursive_mutex restCallbackMutex_; boost::recursive_mutex storedCallbackMutex_; boost::recursive_mutex changeCallbackMutex_; @@ -129,11 +240,9 @@ PImpl() : context_(NULL), - hasStorageArea_(false), argc_(1), argv_(NULL) { - memset(&storageArea_, 0, sizeof(storageArea_)); } }; @@ -1102,10 +1211,11 @@ } - bool OrthancPlugins::InvokeService(_OrthancPluginService service, + bool OrthancPlugins::InvokeService(SharedLibrary& plugin, + _OrthancPluginService service, const void* parameters) { - VLOG(1) << "Calling plugin service: " << service; + VLOG(1) << "Calling service " << service << " from plugin " << plugin.GetPath(); boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); @@ -1261,8 +1371,15 @@ const _OrthancPluginRegisterStorageArea& p = *reinterpret_cast(parameters); - pimpl_->storageArea_ = p; - pimpl_->hasStorageArea_ = true; + if (pimpl_->storageArea_.get() == NULL) + { + pimpl_->storageArea_.reset(new StorageAreaFactory(plugin, p)); + } + else + { + throw OrthancException(ErrorCode_StorageAreaAlreadyRegistered); + } + return true; } @@ -1332,7 +1449,15 @@ const _OrthancPluginRegisterDatabaseBackend& p = *reinterpret_cast(parameters); - pimpl_->database_.reset(new OrthancPluginDatabase(*p.backend, NULL, 0, p.payload)); + + if (pimpl_->database_.get() == NULL) + { + pimpl_->database_.reset(new OrthancPluginDatabase(plugin, *p.backend, NULL, 0, p.payload)); + } + else + { + throw OrthancException(ErrorCode_DatabaseBackendAlreadyRegistered); + } *(p.result) = reinterpret_cast(pimpl_->database_.get()); @@ -1345,7 +1470,16 @@ const _OrthancPluginRegisterDatabaseBackendV2& p = *reinterpret_cast(parameters); - pimpl_->database_.reset(new OrthancPluginDatabase(*p.backend, p.extensions, p.extensionsSize, p.payload)); + + if (pimpl_->database_.get() == NULL) + { + pimpl_->database_.reset(new OrthancPluginDatabase(plugin, *p.backend, p.extensions, + p.extensionsSize, p.payload)); + } + else + { + throw OrthancException(ErrorCode_DatabaseBackendAlreadyRegistered); + } *(p.result) = reinterpret_cast(pimpl_->database_.get()); @@ -1356,6 +1490,7 @@ { const _OrthancPluginDatabaseAnswer& p = *reinterpret_cast(parameters); + if (pimpl_->database_.get() != NULL) { pimpl_->database_->AnswerReceived(p); @@ -1545,124 +1680,65 @@ bool OrthancPlugins::HasStorageArea() const { - return pimpl_->hasStorageArea_; + return pimpl_->storageArea_.get() != NULL; } - bool OrthancPlugins::HasDatabase() const + bool OrthancPlugins::HasDatabaseBackend() const { return pimpl_->database_.get() != NULL; } - - namespace - { - class PluginStorageArea : public IStorageArea - { - private: - _OrthancPluginRegisterStorageArea params_; - - void Free(void* buffer) const - { - if (buffer != NULL) - { - params_.free(buffer); - } - } - - public: - PluginStorageArea(const _OrthancPluginRegisterStorageArea& params) : params_(params) - { - } - - - virtual void Create(const std::string& uuid, - const void* content, - size_t size, - FileContentType type) - { - OrthancPluginErrorCode error = params_.create - (uuid.c_str(), content, size, Plugins::Convert(type)); - - if (error != OrthancPluginErrorCode_Success) - { - throw OrthancException(Plugins::Convert(error)); - } - } - - - virtual void Read(std::string& content, - const std::string& uuid, - FileContentType type) - { - void* buffer = NULL; - int64_t size = 0; - - OrthancPluginErrorCode error = params_.read - (&buffer, &size, uuid.c_str(), Plugins::Convert(type)); - - if (error != OrthancPluginErrorCode_Success) - { - throw OrthancException(Plugins::Convert(error)); - } - - try - { - content.resize(static_cast(size)); - } - catch (...) - { - Free(buffer); - throw; - } - - if (size > 0) - { - memcpy(&content[0], buffer, static_cast(size)); - } - - Free(buffer); - } - - - virtual void Remove(const std::string& uuid, - FileContentType type) - { - OrthancPluginErrorCode error = params_.remove - (uuid.c_str(), Plugins::Convert(type)); - - if (error != OrthancPluginErrorCode_Success) - { - throw OrthancException(Plugins::Convert(error)); - } - } - }; - } - - IStorageArea* OrthancPlugins::CreateStorageArea() { if (!HasStorageArea()) { throw OrthancException(ErrorCode_BadSequenceOfCalls); } + else + { + return pimpl_->storageArea_->Create(); + } + } - return new PluginStorageArea(pimpl_->storageArea_); + + const SharedLibrary& OrthancPlugins::GetStorageAreaLibrary() const + { + if (!HasStorageArea()) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + else + { + return pimpl_->storageArea_->GetSharedLibrary(); + } } - IDatabaseWrapper& OrthancPlugins::GetDatabase() + IDatabaseWrapper& OrthancPlugins::GetDatabaseBackend() { - if (!HasDatabase()) + if (!HasDatabaseBackend()) { throw OrthancException(ErrorCode_BadSequenceOfCalls); } - - return *pimpl_->database_; + else + { + return *pimpl_->database_; + } } - + const SharedLibrary& OrthancPlugins::GetDatabaseBackendLibrary() const + { + if (!HasDatabaseBackend()) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + else + { + return pimpl_->database_->GetSharedLibrary(); + } + } const char* OrthancPlugins::GetProperty(const char* plugin, diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/OrthancPlugins.h --- a/Plugins/Engine/OrthancPlugins.h Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/OrthancPlugins.h Mon Sep 21 13:26:45 2015 +0200 @@ -130,7 +130,8 @@ const char* bodyData, size_t bodySize); - virtual bool InvokeService(_OrthancPluginService service, + virtual bool InvokeService(SharedLibrary& plugin, + _OrthancPluginService service, const void* parameters); virtual void SignalChange(const ServerIndexChange& change); @@ -149,9 +150,13 @@ IStorageArea* CreateStorageArea(); // To be freed after use - bool HasDatabase() const; + const SharedLibrary& GetStorageAreaLibrary() const; + + bool HasDatabaseBackend() const; - IDatabaseWrapper& GetDatabase(); + IDatabaseWrapper& GetDatabaseBackend(); + + const SharedLibrary& GetDatabaseBackendLibrary() const; const char* GetProperty(const char* plugin, _OrthancPluginProperty property) const; diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/PluginsEnumerations.cpp --- a/Plugins/Engine/PluginsEnumerations.cpp Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/PluginsEnumerations.cpp Mon Sep 21 13:26:45 2015 +0200 @@ -295,6 +295,15 @@ case OrthancPluginErrorCode_LuaReturnsNoString: return ErrorCode_LuaReturnsNoString; + case OrthancPluginErrorCode_StorageAreaAlreadyRegistered: + return ErrorCode_StorageAreaAlreadyRegistered; + + case OrthancPluginErrorCode_DatabaseBackendAlreadyRegistered: + return ErrorCode_DatabaseBackendAlreadyRegistered; + + case OrthancPluginErrorCode_DatabasePlugin: + return ErrorCode_DatabasePlugin; + default: return ErrorCode_Plugin; } diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/PluginsManager.cpp --- a/Plugins/Engine/PluginsManager.cpp Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/PluginsManager.cpp Mon Sep 21 13:26:45 2015 +0200 @@ -54,6 +54,19 @@ namespace Orthanc { + PluginsManager::Plugin::Plugin(PluginsManager& pluginManager, + const std::string& path) : + library_(path), + pluginManager_(pluginManager) + { + memset(&context_, 0, sizeof(context_)); + context_.pluginsManager = this; + context_.orthancVersion = ORTHANC_VERSION; + context_.Free = ::free; + context_.InvokeService = InvokeService; + } + + static void CallInitialize(SharedLibrary& plugin, const OrthancPluginContext& context) { @@ -157,15 +170,15 @@ break; } - PluginsManager* that = reinterpret_cast(context->pluginsManager); + Plugin* that = reinterpret_cast(context->pluginsManager); for (std::list::iterator - it = that->serviceProviders_.begin(); - it != that->serviceProviders_.end(); ++it) + it = that->GetPluginManager().serviceProviders_.begin(); + it != that->GetPluginManager().serviceProviders_.end(); ++it) { try { - if ((*it)->InvokeService(service, params)) + if ((*it)->InvokeService(that->GetSharedLibrary(), service, params)) { return OrthancPluginErrorCode_Success; } @@ -185,11 +198,6 @@ PluginsManager::PluginsManager() { - memset(&context_, 0, sizeof(context_)); - context_.pluginsManager = this; - context_.orthancVersion = ORTHANC_VERSION; - context_.Free = ::free; - context_.InvokeService = InvokeService; } PluginsManager::~PluginsManager() @@ -201,7 +209,7 @@ LOG(WARNING) << "Unregistering plugin '" << it->first << "' (version " << it->second->GetVersion() << ")"; - CallFinalize(it->second->GetLibrary()); + CallFinalize(it->second->GetSharedLibrary()); delete it->second; } } @@ -231,27 +239,27 @@ return; } - std::auto_ptr plugin(new Plugin(path)); + std::auto_ptr plugin(new Plugin(*this, path)); - if (!IsOrthancPlugin(plugin->GetLibrary())) + if (!IsOrthancPlugin(plugin->GetSharedLibrary())) { - LOG(ERROR) << "Plugin " << plugin->GetLibrary().GetPath() + LOG(ERROR) << "Plugin " << plugin->GetSharedLibrary().GetPath() << " does not declare the proper entry functions"; throw OrthancException(ErrorCode_SharedLibrary); } - std::string name(CallGetName(plugin->GetLibrary())); + std::string name(CallGetName(plugin->GetSharedLibrary())); if (plugins_.find(name) != plugins_.end()) { LOG(ERROR) << "Plugin '" << name << "' already registered"; throw OrthancException(ErrorCode_SharedLibrary); } - plugin->SetVersion(CallGetVersion(plugin->GetLibrary())); + plugin->SetVersion(CallGetVersion(plugin->GetSharedLibrary())); LOG(WARNING) << "Registering plugin '" << name << "' (version " << plugin->GetVersion() << ")"; - CallInitialize(plugin->GetLibrary(), context_); + CallInitialize(plugin->GetSharedLibrary(), plugin->GetContext()); plugins_[name] = plugin.release(); } @@ -333,5 +341,4 @@ return it->second->GetVersion(); } } - } diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/PluginsManager.h --- a/Plugins/Engine/PluginsManager.h Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/PluginsManager.h Mon Sep 21 13:26:45 2015 +0200 @@ -40,21 +40,22 @@ namespace Orthanc { - class PluginsManager : boost::noncopyable + class PluginsManager : public boost::noncopyable { private: - class Plugin + class Plugin : public boost::noncopyable { private: - SharedLibrary library_; - std::string version_; + OrthancPluginContext context_; + SharedLibrary library_; + std::string version_; + PluginsManager& pluginManager_; public: - Plugin(const std::string& path) : library_(path) - { - } + Plugin(PluginsManager& pluginManager, + const std::string& path); - SharedLibrary& GetLibrary() + SharedLibrary& GetSharedLibrary() { return library_; } @@ -68,11 +69,20 @@ { return version_; } + + PluginsManager& GetPluginManager() + { + return pluginManager_; + } + + OrthancPluginContext& GetContext() + { + return context_; + } }; typedef std::map Plugins; - OrthancPluginContext context_; Plugins plugins_; std::list serviceProviders_; diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/SharedLibrary.cpp --- a/Plugins/Engine/SharedLibrary.cpp Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/SharedLibrary.cpp Mon Sep 21 13:26:45 2015 +0200 @@ -36,6 +36,8 @@ #include "../../Core/Logging.h" #include "../../Core/Toolbox.h" +#include + #if defined(_WIN32) #include #elif defined(__linux) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) @@ -46,20 +48,20 @@ namespace Orthanc { - SharedLibrary::SharedLibrary(const std::string& path) : - path_(path), - handle_(NULL) + SharedLibrary::SharedLibrary(const std::string& path) : handle_(NULL) { + path_ = boost::filesystem::canonical(path).string(); + #if defined(_WIN32) - handle_ = ::LoadLibraryA(path.c_str()); + handle_ = ::LoadLibraryA(path_.c_str()); if (handle_ == NULL) { - LOG(ERROR) << "LoadLibrary(" << path << ") failed: Error " << ::GetLastError(); + LOG(ERROR) << "LoadLibrary(" << path_ << ") failed: Error " << ::GetLastError(); throw OrthancException(ErrorCode_SharedLibrary); } #elif defined(__linux) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) - handle_ = ::dlopen(path.c_str(), RTLD_NOW); + handle_ = ::dlopen(path_.c_str(), RTLD_NOW); if (handle_ == NULL) { std::string explanation; @@ -69,7 +71,7 @@ explanation = ": Error " + std::string(tmp); } - LOG(ERROR) << "dlopen(" << path << ") failed" << explanation; + LOG(ERROR) << "dlopen(" << path_ << ") failed" << explanation; throw OrthancException(ErrorCode_SharedLibrary); } diff -r bad4772b605c -r ffd23c0104af Plugins/Engine/SharedLibrary.h --- a/Plugins/Engine/SharedLibrary.h Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Engine/SharedLibrary.h Mon Sep 21 13:26:45 2015 +0200 @@ -42,7 +42,7 @@ namespace Orthanc { - class SharedLibrary : boost::noncopyable + class SharedLibrary : public boost::noncopyable { public: #if defined(_WIN32) diff -r bad4772b605c -r ffd23c0104af Plugins/Include/orthanc/OrthancCPlugin.h --- a/Plugins/Include/orthanc/OrthancCPlugin.h Fri Sep 18 17:45:59 2015 +0200 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Mon Sep 21 13:26:45 2015 +0200 @@ -262,6 +262,9 @@ OrthancPluginErrorCode_LuaBadOutput = 2033 /*!< The Lua function does not give the expected number of outputs */, OrthancPluginErrorCode_NotLuaPredicate = 2034 /*!< The Lua function is not a predicate (only true/false outputs allowed) */, OrthancPluginErrorCode_LuaReturnsNoString = 2035 /*!< The Lua function does not return a string */, + OrthancPluginErrorCode_StorageAreaAlreadyRegistered = 2036 /*!< Another plugin has already registered a custom storage area */, + OrthancPluginErrorCode_DatabaseBackendAlreadyRegistered = 2037 /*!< Another plugin has already registered a custom database back-end */, + OrthancPluginErrorCode_DatabasePlugin = 2038 /*!< The plugin implementing a custom database back-end does not fulfill the proper interface */, _OrthancPluginErrorCode_INTERNAL = 0x7fffffff } OrthancPluginErrorCode; diff -r bad4772b605c -r ffd23c0104af Resources/ErrorCodes.json --- a/Resources/ErrorCodes.json Fri Sep 18 17:45:59 2015 +0200 +++ b/Resources/ErrorCodes.json Mon Sep 21 13:26:45 2015 +0200 @@ -468,5 +468,20 @@ "Code": 2035, "Name": "LuaReturnsNoString", "Description": "The Lua function does not return a string" + }, + { + "Code": 2036, + "Name": "StorageAreaAlreadyRegistered", + "Description": "Another plugin has already registered a custom storage area" + }, + { + "Code": 2037, + "Name": "DatabaseBackendAlreadyRegistered", + "Description": "Another plugin has already registered a custom database back-end" + }, + { + "Code": 2038, + "Name": "DatabasePlugin", + "Description": "The plugin implementing a custom database back-end does not fulfill the proper interface" } ]