changeset 291:05b4f440a961 refactoring

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 08 Jun 2019 17:42:49 +0200
parents 77d6374435dd
children 0222a9afa866
files CMakeLists.txt Plugin/Plugin.cpp Plugin/StowRs.cpp Plugin/StowRs.h
diffstat 4 files changed, 222 insertions(+), 206 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Jun 08 17:21:53 2019 +0200
+++ b/CMakeLists.txt	Sat Jun 08 17:42:49 2019 +0200
@@ -113,6 +113,7 @@
 
 add_definitions(
   -DHAS_ORTHANC_EXCEPTION=1
+  -DHAS_ORTHANC_FRAMEWORK=1
   -DORTHANC_ENABLE_LOGGING_PLUGIN=1
   -DORTHANC_FRAMEWORK_VERSION_MAJOR=${ORTHANC_FRAMEWORK_MAJOR}
   -DORTHANC_FRAMEWORK_VERSION_MINOR=${ORTHANC_FRAMEWORK_MINOR}
--- a/Plugin/Plugin.cpp	Sat Jun 08 17:21:53 2019 +0200
+++ b/Plugin/Plugin.cpp	Sat Jun 08 17:42:49 2019 +0200
@@ -171,211 +171,7 @@
 
 
 
-
-
-
-
-#include "DicomWebFormatter.h"
-
-class StowServer : public OrthancPlugins::MultipartRestCallback
-{
-private:
-  class Handler : public IHandler
-  {
-  private:
-    OrthancPluginContext*  context_;
-    bool                   xml_;
-    std::string            wadoBase_;
-    std::string            expectedStudy_;
-    bool                   isFirst_;
-    Json::Value            result_;
-    Json::Value            success_;
-    Json::Value            failed_;
-
-  public:
-    Handler(OrthancPluginContext* context,
-            bool xml,
-            const std::string& wadoBase,
-            const std::string& expectedStudy) :
-      context_(context),
-      xml_(xml),
-      wadoBase_(wadoBase),
-      expectedStudy_(expectedStudy),
-      isFirst_(true),
-      result_(Json::objectValue),
-      success_(Json::arrayValue),
-      failed_(Json::arrayValue)
-    {
-    }
-
-    virtual OrthancPluginErrorCode AddPart(const std::string& contentType,
-                                           const std::map<std::string, std::string>& headers,
-                                           const void* data,
-                                           size_t size)
-    {
-      if (contentType != "application/dicom")
-      {
-        throw Orthanc::OrthancException(
-          Orthanc::ErrorCode_UnsupportedMediaType,
-          "The STOW-RS request contains a part that is not "
-          "\"application/dicom\" (it is: \"" + contentType + "\")");
-      }
-
-      Json::Value dicom;
-
-      try
-      {
-        OrthancPlugins::OrthancString s;
-        s.Assign(OrthancPluginDicomBufferToJson(context_, data, size,
-                                                OrthancPluginDicomToJsonFormat_Short,
-                                                OrthancPluginDicomToJsonFlags_None, 256));
-        s.ToJson(dicom);
-      }
-      catch (Orthanc::OrthancException&)
-      {
-        // Bad DICOM file => TODO add to error
-        OrthancPlugins::LogWarning("STOW-RS cannot parse an incoming DICOM file");
-        return OrthancPluginErrorCode_Success;
-      }           
-
-      if (dicom.type() != Json::objectValue ||
-          !dicom.isMember(Orthanc::DICOM_TAG_SERIES_INSTANCE_UID.Format()) ||
-          !dicom.isMember(Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()) ||
-          !dicom.isMember(Orthanc::DICOM_TAG_SOP_INSTANCE_UID.Format()) ||
-          !dicom.isMember(Orthanc::DICOM_TAG_STUDY_INSTANCE_UID.Format()) ||
-          dicom[Orthanc::DICOM_TAG_SERIES_INSTANCE_UID.Format()].type() != Json::stringValue ||
-          dicom[Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()].type() != Json::stringValue ||
-          dicom[Orthanc::DICOM_TAG_SOP_INSTANCE_UID.Format()].type() != Json::stringValue ||
-          dicom[Orthanc::DICOM_TAG_STUDY_INSTANCE_UID.Format()].type() != Json::stringValue)
-      {
-        OrthancPlugins::LogWarning("STOW-RS: Missing a mandatory tag in incoming DICOM file");
-        return OrthancPluginErrorCode_Success;
-      }
-
-      const std::string seriesInstanceUid = dicom[Orthanc::DICOM_TAG_SERIES_INSTANCE_UID.Format()].asString();
-      const std::string sopClassUid = dicom[Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()].asString();
-      const std::string sopInstanceUid = dicom[Orthanc::DICOM_TAG_SOP_INSTANCE_UID.Format()].asString();
-      const std::string studyInstanceUid = dicom[Orthanc::DICOM_TAG_STUDY_INSTANCE_UID.Format()].asString();
-
-      Json::Value item = Json::objectValue;
-      item[OrthancPlugins::DICOM_TAG_REFERENCED_SOP_CLASS_UID.Format()] = sopClassUid;
-      item[OrthancPlugins::DICOM_TAG_REFERENCED_SOP_INSTANCE_UID.Format()] = sopInstanceUid;
-      
-      if (!expectedStudy_.empty() &&
-          studyInstanceUid != expectedStudy_)
-      {
-        OrthancPlugins::LogInfo("STOW-RS request restricted to study [" + expectedStudy_ + 
-                                "]: Ignoring instance from study [" + studyInstanceUid + "]");
-
-        /*item[OrthancPlugins::DICOM_TAG_WARNING_REASON.Format()] =
-          boost::lexical_cast<std::string>(0xB006);  // Elements discarded
-          success.append(item);*/
-      }
-      else
-      {
-        if (isFirst_)
-        {
-          std::string url = wadoBase_ + "studies/" + studyInstanceUid;
-          result_[OrthancPlugins::DICOM_TAG_RETRIEVE_URL.Format()] = url;
-          isFirst_ = false;
-        }
-
-        OrthancPlugins::MemoryBuffer tmp;
-        bool ok = tmp.RestApiPost("/instances", data, size, false);
-        tmp.Clear();
-
-        if (ok)
-        {
-          std::string url = (wadoBase_ + 
-                             "studies/" + studyInstanceUid +
-                             "/series/" + seriesInstanceUid +
-                             "/instances/" + sopInstanceUid);
-
-          item[OrthancPlugins::DICOM_TAG_RETRIEVE_URL.Format()] = url;
-          success_.append(item);      
-        }
-        else
-        {
-          OrthancPlugins::LogError("Orthanc was unable to store one instance in a STOW-RS request");
-          item[OrthancPlugins::DICOM_TAG_FAILURE_REASON.Format()] =
-            boost::lexical_cast<std::string>(0x0110);  // Processing failure
-          failed_.append(item);
-        }
-      }
-      
-      return OrthancPluginErrorCode_Success;
-    }
-
-    virtual OrthancPluginErrorCode Execute(OrthancPluginRestOutput* output)
-    {
-      result_[OrthancPlugins::DICOM_TAG_FAILED_SOP_SEQUENCE.Format()] = failed_;
-      result_[OrthancPlugins::DICOM_TAG_REFERENCED_SOP_SEQUENCE.Format()] = success_;
-
-      std::string answer;
-  
-      {
-        OrthancPlugins::DicomWebFormatter::Locker locker(OrthancPluginDicomWebBinaryMode_Ignore, "");
-        locker.Apply(answer, context_, result_, xml_);
-      }
-      
-      OrthancPluginAnswerBuffer(context_, output, answer.c_str(), answer.size(),
-                                xml_ ? "application/dicom+xml" : "application/dicom+json");
-
-      return OrthancPluginErrorCode_Success;
-    }
-  };
-
-public:
-  virtual IHandler* CreateHandler(OrthancPluginHttpMethod method,
-                                  const std::string& url,
-                                  const std::string& contentType,
-                                  const std::string& subType,
-                                  const std::vector<std::string>& groups,
-                                  const std::map<std::string, std::string>& headers)
-  {
-    OrthancPluginContext* context = OrthancPlugins::GetGlobalContext();
-  
-    if (method != OrthancPluginHttpMethod_Post)
-    {
-      return NULL;
-    }
-
-    const std::string wadoBase = OrthancPlugins::Configuration::GetBaseUrl(headers);
-  
-    std::string expectedStudy;
-    if (groups.size() == 1)
-    {
-      expectedStudy = groups[0];
-    }
-
-    if (expectedStudy.empty())
-    {
-      OrthancPlugins::LogInfo("STOW-RS request without study");
-    }
-    else
-    {
-      OrthancPlugins::LogInfo("STOW-RS request restricted to study UID " + expectedStudy);
-    }
-
-    if (contentType != "multipart/related")
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_UnsupportedMediaType,
-                                      "The Content-Type of a STOW-RS request must be \"multipart/related\"");
-    }
-
-    if (subType != "application/dicom")
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_UnsupportedMediaType,
-                                      "The STOW-RS plugin currently only supports \"application/dicom\" subtype");
-    }
-
-    return new Handler(context, IsXmlExpected(headers), wadoBase, expectedStudy);
-  }
-};
-
-
-static StowServer stowServer_;
-
+static OrthancPlugins::StowServer stowServer_;
 
 
 #include <boost/filesystem.hpp>
--- a/Plugin/StowRs.cpp	Sat Jun 08 17:21:53 2019 +0200
+++ b/Plugin/StowRs.cpp	Sat Jun 08 17:42:49 2019 +0200
@@ -270,3 +270,201 @@
   OrthancPluginAnswerBuffer(context, output, answer.c_str(), answer.size(),
                             isXml ? "application/dicom+xml" : "application/dicom+json");
 }
+
+
+
+
+namespace OrthancPlugins
+{
+  class StowServer::Handler : public IHandler
+  {
+  private:
+    OrthancPluginContext*  context_;
+    bool                   xml_;
+    std::string            wadoBase_;
+    std::string            expectedStudy_;
+    bool                   isFirst_;
+    Json::Value            result_;
+    Json::Value            success_;
+    Json::Value            failed_;
+
+  public:
+    Handler(OrthancPluginContext* context,
+            bool xml,
+            const std::string& wadoBase,
+            const std::string& expectedStudy) :
+      context_(context),
+      xml_(xml),
+      wadoBase_(wadoBase),
+      expectedStudy_(expectedStudy),
+      isFirst_(true),
+      result_(Json::objectValue),
+      success_(Json::arrayValue),
+      failed_(Json::arrayValue)
+    {
+    }
+
+    virtual OrthancPluginErrorCode AddPart(const std::string& contentType,
+                                           const std::map<std::string, std::string>& headers,
+                                           const void* data,
+                                           size_t size)
+    {
+      if (contentType != "application/dicom")
+      {
+        throw Orthanc::OrthancException(
+          Orthanc::ErrorCode_UnsupportedMediaType,
+          "The STOW-RS request contains a part that is not "
+          "\"application/dicom\" (it is: \"" + contentType + "\")");
+      }
+
+      Json::Value dicom;
+
+      try
+      {
+        OrthancString s;
+        s.Assign(OrthancPluginDicomBufferToJson(context_, data, size,
+                                                OrthancPluginDicomToJsonFormat_Short,
+                                                OrthancPluginDicomToJsonFlags_None, 256));
+        s.ToJson(dicom);
+      }
+      catch (Orthanc::OrthancException&)
+      {
+        // Bad DICOM file => TODO add to error
+        LogWarning("STOW-RS cannot parse an incoming DICOM file");
+        return OrthancPluginErrorCode_Success;
+      }           
+
+      if (dicom.type() != Json::objectValue ||
+          !dicom.isMember(Orthanc::DICOM_TAG_SERIES_INSTANCE_UID.Format()) ||
+          !dicom.isMember(Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()) ||
+          !dicom.isMember(Orthanc::DICOM_TAG_SOP_INSTANCE_UID.Format()) ||
+          !dicom.isMember(Orthanc::DICOM_TAG_STUDY_INSTANCE_UID.Format()) ||
+          dicom[Orthanc::DICOM_TAG_SERIES_INSTANCE_UID.Format()].type() != Json::stringValue ||
+          dicom[Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()].type() != Json::stringValue ||
+          dicom[Orthanc::DICOM_TAG_SOP_INSTANCE_UID.Format()].type() != Json::stringValue ||
+          dicom[Orthanc::DICOM_TAG_STUDY_INSTANCE_UID.Format()].type() != Json::stringValue)
+      {
+        LogWarning("STOW-RS: Missing a mandatory tag in incoming DICOM file");
+        return OrthancPluginErrorCode_Success;
+      }
+
+      const std::string seriesInstanceUid = dicom[Orthanc::DICOM_TAG_SERIES_INSTANCE_UID.Format()].asString();
+      const std::string sopClassUid = dicom[Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()].asString();
+      const std::string sopInstanceUid = dicom[Orthanc::DICOM_TAG_SOP_INSTANCE_UID.Format()].asString();
+      const std::string studyInstanceUid = dicom[Orthanc::DICOM_TAG_STUDY_INSTANCE_UID.Format()].asString();
+
+      Json::Value item = Json::objectValue;
+      item[DICOM_TAG_REFERENCED_SOP_CLASS_UID.Format()] = sopClassUid;
+      item[DICOM_TAG_REFERENCED_SOP_INSTANCE_UID.Format()] = sopInstanceUid;
+      
+      if (!expectedStudy_.empty() &&
+          studyInstanceUid != expectedStudy_)
+      {
+        LogInfo("STOW-RS request restricted to study [" + expectedStudy_ + 
+                "]: Ignoring instance from study [" + studyInstanceUid + "]");
+
+        /*item[DICOM_TAG_WARNING_REASON.Format()] =
+          boost::lexical_cast<std::string>(0xB006);  // Elements discarded
+          success.append(item);*/
+      }
+      else
+      {
+        if (isFirst_)
+        {
+          std::string url = wadoBase_ + "studies/" + studyInstanceUid;
+          result_[DICOM_TAG_RETRIEVE_URL.Format()] = url;
+          isFirst_ = false;
+        }
+
+        MemoryBuffer tmp;
+        bool ok = tmp.RestApiPost("/instances", data, size, false);
+        tmp.Clear();
+
+        if (ok)
+        {
+          std::string url = (wadoBase_ + 
+                             "studies/" + studyInstanceUid +
+                             "/series/" + seriesInstanceUid +
+                             "/instances/" + sopInstanceUid);
+
+          item[DICOM_TAG_RETRIEVE_URL.Format()] = url;
+          success_.append(item);      
+        }
+        else
+        {
+          LogError("Orthanc was unable to store one instance in a STOW-RS request");
+          item[DICOM_TAG_FAILURE_REASON.Format()] =
+            boost::lexical_cast<std::string>(0x0110);  // Processing failure
+          failed_.append(item);
+        }
+      }
+      
+      return OrthancPluginErrorCode_Success;
+    }
+
+    virtual OrthancPluginErrorCode Execute(OrthancPluginRestOutput* output)
+    {
+      result_[DICOM_TAG_FAILED_SOP_SEQUENCE.Format()] = failed_;
+      result_[DICOM_TAG_REFERENCED_SOP_SEQUENCE.Format()] = success_;
+
+      std::string answer;
+  
+      {
+        DicomWebFormatter::Locker locker(OrthancPluginDicomWebBinaryMode_Ignore, "");
+        locker.Apply(answer, context_, result_, xml_);
+      }
+      
+      OrthancPluginAnswerBuffer(context_, output, answer.c_str(), answer.size(),
+                                xml_ ? "application/dicom+xml" : "application/dicom+json");
+
+      return OrthancPluginErrorCode_Success;
+    }
+  };
+
+  
+  StowServer::IHandler* StowServer::CreateHandler(OrthancPluginHttpMethod method,
+                                                  const std::string& url,
+                                                  const std::string& contentType,
+                                                  const std::string& subType,
+                                                  const std::vector<std::string>& groups,
+                                                  const std::map<std::string, std::string>& headers)
+  {
+    OrthancPluginContext* context = GetGlobalContext();
+  
+    if (method != OrthancPluginHttpMethod_Post)
+    {
+      return NULL;
+    }
+
+    const std::string wadoBase = Configuration::GetBaseUrl(headers);
+  
+    std::string expectedStudy;
+    if (groups.size() == 1)
+    {
+      expectedStudy = groups[0];
+    }
+
+    if (expectedStudy.empty())
+    {
+      LogInfo("STOW-RS request without study");
+    }
+    else
+    {
+      LogInfo("STOW-RS request restricted to study UID " + expectedStudy);
+    }
+
+    if (contentType != "multipart/related")
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_UnsupportedMediaType,
+                                      "The Content-Type of a STOW-RS request must be \"multipart/related\"");
+    }
+
+    if (subType != "application/dicom")
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_UnsupportedMediaType,
+                                      "The STOW-RS plugin currently only supports \"application/dicom\" subtype");
+    }
+
+    return new Handler(context, IsXmlExpected(headers), wadoBase, expectedStudy);
+  }
+}
--- a/Plugin/StowRs.h	Sat Jun 08 17:21:53 2019 +0200
+++ b/Plugin/StowRs.h	Sat Jun 08 17:42:49 2019 +0200
@@ -23,10 +23,31 @@
 
 #include "Configuration.h"
 
+#include <Plugins/Samples/Common/OrthancPluginCppWrapper.h>
+
+
 bool IsXmlExpected(const std::map<std::string, std::string>& headers);
 
-  bool IsXmlExpected(const OrthancPluginHttpRequest* request);
+bool IsXmlExpected(const OrthancPluginHttpRequest* request);
 
 void StowCallback(OrthancPluginRestOutput* output,
                   const char* url,
                   const OrthancPluginHttpRequest* request);
+
+
+namespace OrthancPlugins
+{
+  class StowServer : public MultipartRestCallback
+  {
+  private:
+    class Handler;
+    
+  public:
+    virtual IHandler* CreateHandler(OrthancPluginHttpMethod method,
+                                    const std::string& url,
+                                    const std::string& contentType,
+                                    const std::string& subType,
+                                    const std::vector<std::string>& groups,
+                                    const std::map<std::string, std::string>& headers);
+  };
+}