changeset 2519:2e6b7862ccf2

ParseAnonymizationRequest/ParseModifyRequest now in DicomModification
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 29 Mar 2018 14:52:11 +0200
parents 63d2cc0fb40a
children b94ed97508e6
files Core/DicomParsing/DicomModification.cpp Core/DicomParsing/DicomModification.h OrthancServer/LuaScripting.cpp OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp OrthancServer/OrthancRestApi/OrthancRestApi.h
diffstat 5 files changed, 210 insertions(+), 207 deletions(-) [+]
line wrap: on
line diff
--- a/Core/DicomParsing/DicomModification.cpp	Thu Mar 29 14:41:41 2018 +0200
+++ b/Core/DicomParsing/DicomModification.cpp	Thu Mar 29 14:52:11 2018 +0200
@@ -1004,4 +1004,198 @@
       }
     }
   }
+
+
+  static bool IsDatabaseKey(const DicomTag& tag)
+  {
+    return (tag == DICOM_TAG_PATIENT_ID ||
+            tag == DICOM_TAG_STUDY_INSTANCE_UID ||
+            tag == DICOM_TAG_SERIES_INSTANCE_UID ||
+            tag == DICOM_TAG_SOP_INSTANCE_UID);
+  }
+
+
+  static void ParseListOfTags(DicomModification& target,
+                              const Json::Value& query,
+                              DicomModification::TagOperation operation,
+                              bool force)
+  {
+    if (!query.isArray())
+    {
+      throw OrthancException(ErrorCode_BadRequest);
+    }
+
+    for (Json::Value::ArrayIndex i = 0; i < query.size(); i++)
+    {
+      std::string name = query[i].asString();
+
+      DicomTag tag = FromDcmtkBridge::ParseTag(name);
+
+      if (!force && IsDatabaseKey(tag))
+      {
+        LOG(ERROR) << "Marking tag \"" << name << "\" as to be "
+                   << (operation == DicomModification::TagOperation_Keep ? "kept" : "removed")
+                   << " requires the \"Force\" option to be set to true";
+        throw OrthancException(ErrorCode_BadRequest);
+      }
+
+      switch (operation)
+      {
+        case DicomModification::TagOperation_Keep:
+          target.Keep(tag);
+          VLOG(1) << "Keep: " << name << " " << tag << std::endl;
+          break;
+
+        case DicomModification::TagOperation_Remove:
+          target.Remove(tag);
+          VLOG(1) << "Remove: " << name << " " << tag << std::endl;
+          break;
+
+        default:
+          throw OrthancException(ErrorCode_InternalError);
+      }
+    }
+  }
+
+
+  static void ParseReplacements(DicomModification& target,
+                                const Json::Value& replacements,
+                                bool force)
+  {
+    if (!replacements.isObject())
+    {
+      throw OrthancException(ErrorCode_BadRequest);
+    }
+
+    Json::Value::Members members = replacements.getMemberNames();
+    for (size_t i = 0; i < members.size(); i++)
+    {
+      const std::string& name = members[i];
+      const Json::Value& value = replacements[name];
+
+      DicomTag tag = FromDcmtkBridge::ParseTag(name);
+
+      if (!force && IsDatabaseKey(tag))
+      {
+        LOG(ERROR) << "Marking tag \"" << name << "\" as to be replaced "
+                   << "requires the \"Force\" option to be set to true";
+        throw OrthancException(ErrorCode_BadRequest);
+      }
+
+      target.Replace(tag, value, false);
+
+      VLOG(1) << "Replace: " << name << " " << tag 
+              << " == " << value.toStyledString() << std::endl;
+    }
+  }
+
+
+  static bool GetBooleanValue(const std::string& member,
+                              const Json::Value& json,
+                              bool defaultValue)
+  {
+    if (!json.isMember(member))
+    {
+      return defaultValue;
+    }
+    else if (json[member].type() == Json::booleanValue)
+    {
+      return json[member].asBool();
+    }
+    else
+    {
+      LOG(ERROR) << "Member \"" << member << "\" should be a Boolean value";
+      throw OrthancException(ErrorCode_BadFileFormat);
+    }
+  }
+
+
+  void DicomModification::ParseModifyRequest(const Json::Value& request)
+  {
+    if (!request.isObject())
+    {
+      throw OrthancException(ErrorCode_BadFileFormat);
+    }
+
+    bool force = GetBooleanValue("Force", request, false);
+      
+    if (GetBooleanValue("RemovePrivateTags", request, false))
+    {
+      SetRemovePrivateTags(true);
+    }
+
+    if (request.isMember("Remove"))
+    {
+      ParseListOfTags(*this, request["Remove"], TagOperation_Remove, force);
+    }
+
+    if (request.isMember("Replace"))
+    {
+      ParseReplacements(*this, request["Replace"], force);
+    }
+
+    // The "Keep" operation only makes sense for the tags
+    // StudyInstanceUID, SeriesInstanceUID and SOPInstanceUID. Avoid
+    // this feature as much as possible, as this breaks the DICOM
+    // model of the real world, except if you know exactly what
+    // you're doing!
+    if (request.isMember("Keep"))
+    {
+      ParseListOfTags(*this, request["Keep"], TagOperation_Keep, force);
+    }
+  }
+
+
+  void DicomModification::ParseAnonymizationRequest(bool& patientNameReplaced,
+                                                    const Json::Value& request)
+  {
+    if (!request.isObject())
+    {
+      throw OrthancException(ErrorCode_BadFileFormat);
+    }
+
+    bool force = GetBooleanValue("Force", request, false);
+      
+    // As of Orthanc 1.3.0, the default anonymization is done
+    // according to PS 3.15-2017c Table E.1-1 (basic profile)
+    DicomVersion version = DicomVersion_2017c;
+    if (request.isMember("DicomVersion"))
+    {
+      if (request["DicomVersion"].type() != Json::stringValue)
+      {
+        throw OrthancException(ErrorCode_BadFileFormat);
+      }
+      else
+      {
+        version = StringToDicomVersion(request["DicomVersion"].asString());
+      }
+    }
+        
+    SetupAnonymization(version);
+
+    std::string patientName = GetReplacementAsString(DICOM_TAG_PATIENT_NAME);    
+
+    if (GetBooleanValue("KeepPrivateTags", request, false))
+    {
+      SetRemovePrivateTags(false);
+    }
+
+    if (request.isMember("Remove"))
+    {
+      ParseListOfTags(*this, request["Remove"], TagOperation_Remove, force);
+    }
+
+    if (request.isMember("Replace"))
+    {
+      ParseReplacements(*this, request["Replace"], force);
+    }
+
+    if (request.isMember("Keep"))
+    {
+      ParseListOfTags(*this, request["Keep"], TagOperation_Keep, force);
+    }
+
+    patientNameReplaced = (IsReplaced(DICOM_TAG_PATIENT_NAME) &&
+                           GetReplacement(DICOM_TAG_PATIENT_NAME) == patientName);
+  }
 }
--- a/Core/DicomParsing/DicomModification.h	Thu Mar 29 14:41:41 2018 +0200
+++ b/Core/DicomParsing/DicomModification.h	Thu Mar 29 14:52:11 2018 +0200
@@ -46,6 +46,13 @@
      * (3) Replace tags
      **/
 
+  public:
+    enum TagOperation
+    {
+      TagOperation_Keep,
+      TagOperation_Remove
+    };
+
   private:
     class RelationshipsVisitor;
 
@@ -139,5 +146,10 @@
     {
       return allowManualIdentifiers_;
     }
+
+    void ParseModifyRequest(const Json::Value& request);
+
+    void ParseAnonymizationRequest(bool& patientNameReplaced,
+                                   const Json::Value& request);
   };
 }
--- a/OrthancServer/LuaScripting.cpp	Thu Mar 29 14:41:41 2018 +0200
+++ b/OrthancServer/LuaScripting.cpp	Thu Mar 29 14:52:11 2018 +0200
@@ -274,7 +274,7 @@
     {
       LOG(INFO) << "Lua script to modify resource " << parameters["Resource"].asString();
       std::auto_ptr<DicomModification> modification(new DicomModification);
-      OrthancRestApi::ParseModifyRequest(*modification, parameters);
+      modification->ParseModifyRequest(parameters);
 
       std::auto_ptr<ModifyInstanceCommand> command
         (new ModifyInstanceCommand(context_, RequestOrigin_Lua, modification.release()));
--- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Thu Mar 29 14:41:41 2018 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Thu Mar 29 14:52:11 2018 +0200
@@ -46,95 +46,7 @@
 {
   // Modification of DICOM instances ------------------------------------------
 
-  enum TagOperation
-  {
-    TagOperation_Keep,
-    TagOperation_Remove
-  };
-
-  static bool IsDatabaseKey(const DicomTag& tag)
-  {
-    return (tag == DICOM_TAG_PATIENT_ID ||
-            tag == DICOM_TAG_STUDY_INSTANCE_UID ||
-            tag == DICOM_TAG_SERIES_INSTANCE_UID ||
-            tag == DICOM_TAG_SOP_INSTANCE_UID);
-  }
-
-  static void ParseListOfTags(DicomModification& target,
-                              const Json::Value& query,
-                              TagOperation operation,
-                              bool force)
-  {
-    if (!query.isArray())
-    {
-      throw OrthancException(ErrorCode_BadRequest);
-    }
-
-    for (Json::Value::ArrayIndex i = 0; i < query.size(); i++)
-    {
-      std::string name = query[i].asString();
-
-      DicomTag tag = FromDcmtkBridge::ParseTag(name);
-
-      if (!force && IsDatabaseKey(tag))
-      {
-        LOG(ERROR) << "Marking tag \"" << name << "\" as to be "
-                   << (operation == TagOperation_Keep ? "kept" : "removed")
-                   << " requires the \"Force\" option to be set to true";
-        throw OrthancException(ErrorCode_BadRequest);
-      }
-
-      switch (operation)
-      {
-        case TagOperation_Keep:
-          target.Keep(tag);
-          VLOG(1) << "Keep: " << name << " " << tag << std::endl;
-          break;
-
-        case TagOperation_Remove:
-          target.Remove(tag);
-          VLOG(1) << "Remove: " << name << " " << tag << std::endl;
-          break;
-
-        default:
-          throw OrthancException(ErrorCode_InternalError);
-      }
-    }
-  }
-
-
-  static void ParseReplacements(DicomModification& target,
-                                const Json::Value& replacements,
-                                bool force)
-  {
-    if (!replacements.isObject())
-    {
-      throw OrthancException(ErrorCode_BadRequest);
-    }
-
-    Json::Value::Members members = replacements.getMemberNames();
-    for (size_t i = 0; i < members.size(); i++)
-    {
-      const std::string& name = members[i];
-      const Json::Value& value = replacements[name];
-
-      DicomTag tag = FromDcmtkBridge::ParseTag(name);
-
-      if (!force && IsDatabaseKey(tag))
-      {
-        LOG(ERROR) << "Marking tag \"" << name << "\" as to be replaced "
-                   << "requires the \"Force\" option to be set to true";
-        throw OrthancException(ErrorCode_BadRequest);
-      }
-
-      target.Replace(tag, value, false);
-
-      VLOG(1) << "Replace: " << name << " " << tag 
-              << " == " << value.toStyledString() << std::endl;
-    }
-  }
-
-
+  
   static std::string GeneratePatientName(ServerContext& context)
   {
     uint64_t seq = context.GetIndex().IncrementGlobalSequence(GlobalProperty_AnonymizationSequence);
@@ -142,118 +54,6 @@
   }
 
 
-  static bool GetBooleanValue(const std::string& member,
-                              const Json::Value& json,
-                              bool defaultValue)
-  {
-    if (!json.isMember(member))
-    {
-      return defaultValue;
-    }
-    else if (json[member].type() == Json::booleanValue)
-    {
-      return json[member].asBool();
-    }
-    else
-    {
-      LOG(ERROR) << "Member \"" << member << "\" should be a Boolean value";
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-  }
-
-
-  void OrthancRestApi::ParseModifyRequest(DicomModification& target,
-                                          const Json::Value& request)
-  {
-    if (!request.isObject())
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    bool force = GetBooleanValue("Force", request, false);
-      
-    if (GetBooleanValue("RemovePrivateTags", request, false))
-    {
-      target.SetRemovePrivateTags(true);
-    }
-
-    if (request.isMember("Remove"))
-    {
-      ParseListOfTags(target, request["Remove"], TagOperation_Remove, force);
-    }
-
-    if (request.isMember("Replace"))
-    {
-      ParseReplacements(target, request["Replace"], force);
-    }
-
-    // The "Keep" operation only makes sense for the tags
-    // StudyInstanceUID, SeriesInstanceUID and SOPInstanceUID. Avoid
-    // this feature as much as possible, as this breaks the DICOM
-    // model of the real world, except if you know exactly what
-    // you're doing!
-    if (request.isMember("Keep"))
-    {
-      ParseListOfTags(target, request["Keep"], TagOperation_Keep, force);
-    }
-  }
-
-
-  static void ParseAnonymizationRequest(DicomModification& target,
-                                        bool& patientNameReplaced,
-                                        const Json::Value& request)
-  {
-    if (!request.isObject())
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    bool force = GetBooleanValue("Force", request, false);
-      
-    // As of Orthanc 1.3.0, the default anonymization is done
-    // according to PS 3.15-2017c Table E.1-1 (basic profile)
-    DicomVersion version = DicomVersion_2017c;
-    if (request.isMember("DicomVersion"))
-    {
-      if (request["DicomVersion"].type() != Json::stringValue)
-      {
-        throw OrthancException(ErrorCode_BadFileFormat);
-      }
-      else
-      {
-        version = StringToDicomVersion(request["DicomVersion"].asString());
-      }
-    }
-        
-    target.SetupAnonymization(version);
-
-    std::string patientName = target.GetReplacementAsString(DICOM_TAG_PATIENT_NAME);    
-
-    if (GetBooleanValue("KeepPrivateTags", request, false))
-    {
-      target.SetRemovePrivateTags(false);
-    }
-
-    if (request.isMember("Remove"))
-    {
-      ParseListOfTags(target, request["Remove"], TagOperation_Remove, force);
-    }
-
-    if (request.isMember("Replace"))
-    {
-      ParseReplacements(target, request["Replace"], force);
-    }
-
-    if (request.isMember("Keep"))
-    {
-      ParseListOfTags(target, request["Keep"], TagOperation_Keep, force);
-    }
-
-    patientNameReplaced = (target.IsReplaced(DICOM_TAG_PATIENT_NAME) &&
-                           target.GetReplacement(DICOM_TAG_PATIENT_NAME) == patientName);
-  }
-
-
   static void ParseModifyRequest(DicomModification& target,
                                  const RestApiPostCall& call)
   {
@@ -262,7 +62,7 @@
     Json::Value request;
     if (call.ParseJsonRequest(request))
     {
-      OrthancRestApi::ParseModifyRequest(target, request);
+      target.ParseModifyRequest(request);
     }
     else
     {
@@ -281,7 +81,7 @@
         request.isObject())
     {
       bool patientNameReplaced;
-      ParseAnonymizationRequest(target, patientNameReplaced, request);
+      target.ParseAnonymizationRequest(patientNameReplaced, request);
 
       if (patientNameReplaced)
       {
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.h	Thu Mar 29 14:41:41 2018 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestApi.h	Thu Mar 29 14:52:11 2018 +0200
@@ -96,8 +96,5 @@
                               const std::string& publicId,
                               ResourceType resourceType,
                               StoreStatus status) const;
-
-    static void ParseModifyRequest(DicomModification& target,
-                                   const Json::Value& request);
   };
 }