changeset 1145:0479d02c6778

Plugins can retrieve the path to Orthanc and to its configuration file
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 11 Sep 2014 13:06:16 +0200
parents fef79a477e09
children 200fcac0deb4
files Core/Toolbox.cpp NEWS OrthancServer/OrthancInitialization.cpp OrthancServer/OrthancInitialization.h OrthancServer/OrthancRestApi/OrthancRestResources.cpp OrthancServer/Scheduler/DeleteInstanceCommand.cpp OrthancServer/ServerContext.cpp OrthancServer/ServerContext.h OrthancServer/ServerIndex.h Plugins/Engine/OrthancPlugins.cpp Plugins/OrthancCPlugin/OrthancCPlugin.h Plugins/Samples/Basic/Plugin.c
diffstat 12 files changed, 195 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/Core/Toolbox.cpp	Thu Sep 11 10:26:32 2014 +0200
+++ b/Core/Toolbox.cpp	Thu Sep 11 13:06:16 2014 +0200
@@ -494,7 +494,7 @@
 
 
 #if defined(_WIN32)
-  std::string Toolbox::GetPathToExecutable()
+  static std::string GetPathToExecutableInternal()
   {
     // Yes, this is ugly, but there is no simple way to get the 
     // required buffer size, so we use a big constant
@@ -504,7 +504,7 @@
   }
 
 #elif defined(__linux) || defined(__FreeBSD_kernel__)
-  std::string Toolbox::GetPathToExecutable()
+  static std::string GetPathToExecutableInternal()
   {
     std::vector<char> buffer(PATH_MAX + 1);
     ssize_t bytes = readlink("/proc/self/exe", &buffer[0], buffer.size() - 1);
@@ -517,7 +517,7 @@
   }
 
 #elif defined(__APPLE__) && defined(__MACH__)
-  std::string Toolbox::GetPathToExecutable()
+  static std::string GetPathToExecutableInternal()
   {
     char pathbuf[PATH_MAX + 1];
     unsigned int  bufsize = static_cast<int>(sizeof(pathbuf));
@@ -532,10 +532,17 @@
 #endif
 
 
+  std::string Toolbox::GetPathToExecutable()
+  {
+    boost::filesystem::path p(GetPathToExecutableInternal());
+    return boost::filesystem::absolute(p).string();
+  }
+
+
   std::string Toolbox::GetDirectoryOfExecutable()
   {
-    boost::filesystem::path p(GetPathToExecutable());
-    return p.parent_path().string();
+    boost::filesystem::path p(GetPathToExecutableInternal());
+    return boost::filesystem::absolute(p.parent_path()).string();
   }
 
 
--- a/NEWS	Thu Sep 11 10:26:32 2014 +0200
+++ b/NEWS	Thu Sep 11 13:06:16 2014 +0200
@@ -15,6 +15,7 @@
 
 * Configuration option to enable HTTP Keep-Alive
 * Configuration option to disable the logging of exported resources in "/exports"
+* Plugins can retrieve the path to Orthanc and to its configuration file
 * Refactoring of HttpOutput ("Content-Length" header is now always sent)
 * "/tools/create-dicom" now accepts the "PatientID" DICOM tag (+ updated sample)
 * Upgrade to Mongoose 3.8
--- a/OrthancServer/OrthancInitialization.cpp	Thu Sep 11 10:26:32 2014 +0200
+++ b/OrthancServer/OrthancInitialization.cpp	Thu Sep 11 13:06:16 2014 +0200
@@ -61,6 +61,7 @@
   static boost::mutex globalMutex_;
   static std::auto_ptr<Json::Value> configuration_;
   static boost::filesystem::path defaultDirectory_;
+  static std::string configurationAbsolutePath_;
 
 
   static void ReadGlobalConfiguration(const char* configurationFile)
@@ -74,6 +75,7 @@
       Toolbox::ReadFile(content, configurationFile);
       defaultDirectory_ = boost::filesystem::path(configurationFile).parent_path();
       LOG(WARNING) << "Using the configuration from: " << configurationFile;
+      configurationAbsolutePath_ = boost::filesystem::absolute(configurationFile).string();
     }
     else
     {
@@ -93,6 +95,7 @@
         p /= "Configuration.json";
         Toolbox::ReadFile(content, p.string());
         LOG(WARNING) << "Using the configuration from: " << p.string();
+        configurationAbsolutePath_ = boost::filesystem::absolute(p).string();
       }
       catch (OrthancException&)
       {
@@ -103,6 +106,7 @@
 #endif
     }
 
+
     Json::Reader reader;
     if (!reader.parse(content, *configuration_))
     {
@@ -643,4 +647,11 @@
 
     peers.removeMember(symbolicName.c_str());
   }
+
+
+  
+  const std::string& Configuration::GetConfigurationAbsolutePath()
+  {
+    return configurationAbsolutePath_;
+  }
 }
--- a/OrthancServer/OrthancInitialization.h	Thu Sep 11 10:26:32 2014 +0200
+++ b/OrthancServer/OrthancInitialization.h	Thu Sep 11 13:06:16 2014 +0200
@@ -100,5 +100,7 @@
                            const OrthancPeerParameters& peer);
 
     static void RemovePeer(const std::string& symbolicName);
+
+    static const std::string& GetConfigurationAbsolutePath();
   };
 }
--- a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp	Thu Sep 11 10:26:32 2014 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp	Thu Sep 11 13:06:16 2014 +0200
@@ -64,7 +64,7 @@
   static void DeleteSingleResource(RestApiDeleteCall& call)
   {
     Json::Value result;
-    if (OrthancRestApi::GetIndex(call).DeleteResource(result, call.GetUriComponent("id", ""), resourceType))
+    if (OrthancRestApi::GetContext(call).DeleteResource(result, call.GetUriComponent("id", ""), resourceType))
     {
       call.GetOutput().AnswerJson(result);
     }
--- a/OrthancServer/Scheduler/DeleteInstanceCommand.cpp	Thu Sep 11 10:26:32 2014 +0200
+++ b/OrthancServer/Scheduler/DeleteInstanceCommand.cpp	Thu Sep 11 13:06:16 2014 +0200
@@ -47,7 +47,7 @@
       try
       {
         Json::Value tmp;
-        context_.GetIndex().DeleteResource(tmp, *it, ResourceType_Instance);
+        context_.DeleteResource(tmp, *it, ResourceType_Instance);
       }
       catch (OrthancException& e)
       {
--- a/OrthancServer/ServerContext.cpp	Thu Sep 11 10:26:32 2014 +0200
+++ b/OrthancServer/ServerContext.cpp	Thu Sep 11 13:06:16 2014 +0200
@@ -512,4 +512,12 @@
       return true;
     }
   }
+
+
+  bool ServerContext::DeleteResource(Json::Value& target,
+                                     const std::string& uuid,
+                                     ResourceType expectedType)
+  {
+    return index_.DeleteResource(target, uuid, expectedType);
+  }
 }
--- a/OrthancServer/ServerContext.h	Thu Sep 11 10:26:32 2014 +0200
+++ b/OrthancServer/ServerContext.h	Thu Sep 11 13:06:16 2014 +0200
@@ -198,5 +198,9 @@
     {
       plugins_ = &plugins;
     }
+
+    bool DeleteResource(Json::Value& target,
+                        const std::string& uuid,
+                        ResourceType expectedType);
   };
 }
--- a/OrthancServer/ServerIndex.h	Thu Sep 11 10:26:32 2014 +0200
+++ b/OrthancServer/ServerIndex.h	Thu Sep 11 13:06:16 2014 +0200
@@ -143,7 +143,7 @@
     void GetAllUuids(Json::Value& target,
                      ResourceType resourceType);
 
-    bool DeleteResource(Json::Value& target,
+    bool DeleteResource(Json::Value& target /* out */,
                         const std::string& uuid,
                         ResourceType expectedType);
 
--- a/Plugins/Engine/OrthancPlugins.cpp	Thu Sep 11 10:26:32 2014 +0200
+++ b/Plugins/Engine/OrthancPlugins.cpp	Thu Sep 11 13:06:16 2014 +0200
@@ -38,6 +38,7 @@
 #include "../../Core/HttpServer/HttpOutput.h"
 #include "../../Core/ImageFormats/PngWriter.h"
 #include "../../OrthancServer/ServerToolbox.h"
+#include "../../OrthancServer/OrthancInitialization.h"
 
 #include <boost/regex.hpp> 
 #include <glog/logging.h>
@@ -573,8 +574,8 @@
   void OrthancPlugins::LookupResource(_OrthancPluginService service,
                                           const void* parameters)
   {
-    const _OrthancPluginLookupResource& p = 
-      *reinterpret_cast<const _OrthancPluginLookupResource*>(parameters);
+    const _OrthancPluginRetrieveDynamicString& p = 
+      *reinterpret_cast<const _OrthancPluginRetrieveDynamicString*>(parameters);
 
     /**
      * The enumeration below only uses the tags that are indexed in
@@ -617,7 +618,7 @@
     }
 
     std::list<std::string> result;
-    pimpl_->context_.GetIndex().LookupTagValue(result, tag, p.identifier, level);
+    pimpl_->context_.GetIndex().LookupTagValue(result, tag, p.argument, level);
 
     if (result.size() == 1)
     {
@@ -743,10 +744,31 @@
 
 
   bool OrthancPlugins::InvokeService(_OrthancPluginService service,
-                                         const void* parameters)
+                                     const void* parameters)
   {
     switch (service)
     {
+      case _OrthancPluginService_GetOrthancPath:
+      {
+        std::string s = Toolbox::GetPathToExecutable();
+        *reinterpret_cast<const _OrthancPluginRetrieveDynamicString*>(parameters)->result = CopyString(s);
+        return true;
+      }
+
+      case _OrthancPluginService_GetOrthancDirectory:
+      {
+        std::string s = Toolbox::GetDirectoryOfExecutable();
+        *reinterpret_cast<const _OrthancPluginRetrieveDynamicString*>(parameters)->result = CopyString(s);
+        return true;
+      }
+
+      case _OrthancPluginService_GetConfigurationPath:
+      {
+        *reinterpret_cast<const _OrthancPluginRetrieveDynamicString*>(parameters)->result = 
+          CopyString(Configuration::GetConfigurationAbsolutePath());
+        return true;
+      }
+
       case _OrthancPluginService_RegisterRestCallback:
         RegisterRestCallback(parameters);
         return true;
--- a/Plugins/OrthancCPlugin/OrthancCPlugin.h	Thu Sep 11 10:26:32 2014 +0200
+++ b/Plugins/OrthancCPlugin/OrthancCPlugin.h	Thu Sep 11 13:06:16 2014 +0200
@@ -237,6 +237,9 @@
     _OrthancPluginService_LogInfo = 1,
     _OrthancPluginService_LogWarning = 2,
     _OrthancPluginService_LogError = 3,
+    _OrthancPluginService_GetOrthancPath = 4,
+    _OrthancPluginService_GetOrthancDirectory = 5,
+    _OrthancPluginService_GetConfigurationPath = 6,
 
     /* Registration of callbacks */
     _OrthancPluginService_RegisterRestCallback = 1000,
@@ -941,9 +944,9 @@
 
   typedef struct
   {
-    char** result;
-    const char* identifier;
-  } _OrthancPluginLookupResource;
+    char**       result;
+    const char*  argument;
+  } _OrthancPluginRetrieveDynamicString;
 
   /**
    * @brief Look for a patient.
@@ -963,9 +966,9 @@
   {
     char* result;
 
-    _OrthancPluginLookupResource params;
+    _OrthancPluginRetrieveDynamicString params;
     params.result = &result;
-    params.identifier = patientID;
+    params.argument = patientID;
 
     if (context->InvokeService(context, _OrthancPluginService_LookupPatient, &params))
     {
@@ -997,9 +1000,9 @@
   {
     char* result;
 
-    _OrthancPluginLookupResource params;
+    _OrthancPluginRetrieveDynamicString params;
     params.result = &result;
-    params.identifier = studyUID;
+    params.argument = studyUID;
 
     if (context->InvokeService(context, _OrthancPluginService_LookupStudy, &params))
     {
@@ -1031,9 +1034,9 @@
   {
     char* result;
 
-    _OrthancPluginLookupResource params;
+    _OrthancPluginRetrieveDynamicString params;
     params.result = &result;
-    params.identifier = accessionNumber;
+    params.argument = accessionNumber;
 
     if (context->InvokeService(context, _OrthancPluginService_LookupStudyWithAccessionNumber, &params))
     {
@@ -1065,9 +1068,9 @@
   {
     char* result;
 
-    _OrthancPluginLookupResource params;
+    _OrthancPluginRetrieveDynamicString params;
     params.result = &result;
-    params.identifier = seriesUID;
+    params.argument = seriesUID;
 
     if (context->InvokeService(context, _OrthancPluginService_LookupSeries, &params))
     {
@@ -1099,9 +1102,9 @@
   {
     char* result;
 
-    _OrthancPluginLookupResource params;
+    _OrthancPluginRetrieveDynamicString params;
     params.result = &result;
-    params.identifier = sopInstanceUID;
+    params.argument = sopInstanceUID;
 
     if (context->InvokeService(context, _OrthancPluginService_LookupInstance, &params))
     {
@@ -1546,6 +1549,99 @@
   }
 
 
+
+  /**
+   * @brief Return the path to the Orthanc executable.
+   *
+   * This function returns the path to the Orthanc executable.
+   * 
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @return NULL in the case of an error, or a newly allocated string
+   * containing the path. This string must be freed by
+   * OrthancPluginFreeString().
+   **/
+  ORTHANC_PLUGIN_INLINE char *OrthancPluginGetOrthancPath(OrthancPluginContext* context)
+  {
+    char* result;
+
+    _OrthancPluginRetrieveDynamicString params;
+    params.result = &result;
+    params.argument = NULL;
+
+    if (context->InvokeService(context, _OrthancPluginService_GetOrthancPath, &params))
+    {
+      /* Error */
+      return NULL;
+    }
+    else
+    {
+      return result;
+    }
+  }
+
+
+  /**
+   * @brief Return the directory containing the Orthanc.
+   *
+   * This function returns the path to the directory containing the Orthanc executable.
+   * 
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @return NULL in the case of an error, or a newly allocated string
+   * containing the path. This string must be freed by
+   * OrthancPluginFreeString().
+   **/
+  ORTHANC_PLUGIN_INLINE char *OrthancPluginGetOrthancDirectory(OrthancPluginContext* context)
+  {
+    char* result;
+
+    _OrthancPluginRetrieveDynamicString params;
+    params.result = &result;
+    params.argument = NULL;
+
+    if (context->InvokeService(context, _OrthancPluginService_GetOrthancDirectory, &params))
+    {
+      /* Error */
+      return NULL;
+    }
+    else
+    {
+      return result;
+    }
+  }
+
+
+  /**
+   * @brief Return the path to the configuration file.
+   *
+   * This function returns the path to the configuration file that was
+   * specified when starting Orthanc.
+   * 
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @return NULL in the case of an error, or a newly allocated string
+   * containing the path. This string must be freed by
+   * OrthancPluginFreeString().
+   **/
+  ORTHANC_PLUGIN_INLINE char *OrthancPluginGetConfigurationPath(OrthancPluginContext* context)
+  {
+    char* result;
+
+    _OrthancPluginRetrieveDynamicString params;
+    params.result = &result;
+    params.argument = NULL;
+
+    if (context->InvokeService(context, _OrthancPluginService_GetConfigurationPath, &params))
+    {
+      /* Error */
+      return NULL;
+    }
+    else
+    {
+      return result;
+    }
+  }
+
+
+
 #ifdef  __cplusplus
 }
 #endif
--- a/Plugins/Samples/Basic/Plugin.c	Thu Sep 11 10:26:32 2014 +0200
+++ b/Plugins/Samples/Basic/Plugin.c	Thu Sep 11 13:06:16 2014 +0200
@@ -248,7 +248,7 @@
 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c)
 {
   OrthancPluginMemoryBuffer tmp;
-  char info[1024];
+  char info[1024], *s;
 
   context = c;
   OrthancPluginLogWarning(context, "Sample plugin is initializing");
@@ -265,9 +265,26 @@
     return -1;
   }
 
+  /* Print some information about Orthanc */
   sprintf(info, "The version of Orthanc is '%s'", context->orthancVersion);
-  OrthancPluginLogInfo(context, info);
+  OrthancPluginLogWarning(context, info);
+
+  s = OrthancPluginGetOrthancPath(context);
+  sprintf(info, "  Path to Orthanc: %s", s);
+  OrthancPluginLogWarning(context, info);
+  OrthancPluginFreeString(context, s);
 
+  s = OrthancPluginGetOrthancDirectory(context);
+  sprintf(info, "  Directory of Orthanc: %s", s);
+  OrthancPluginLogWarning(context, info);
+  OrthancPluginFreeString(context, s);
+
+  s = OrthancPluginGetConfigurationPath(context);
+  sprintf(info, "  Path to configuration file: %s", s);
+  OrthancPluginLogWarning(context, info);
+  OrthancPluginFreeString(context, s);
+
+  /* Register the callbacks */
   OrthancPluginRegisterRestCallback(context, "/(plu.*)/hello", Callback1);
   OrthancPluginRegisterRestCallback(context, "/plu.*/image", Callback2);
   OrthancPluginRegisterRestCallback(context, "/plugin/instances/([^/]+)/info", Callback3);