changeset 5700:1fab9ddaf702 find-refactoring

webdav using ResourceFinder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 12 Jul 2024 15:02:59 +0200
parents e8e028aed89f
children 388aef262b1b
files OrthancServer/Sources/OrthancFindRequestHandler.cpp OrthancServer/Sources/OrthancWebDav.cpp OrthancServer/Sources/OrthancWebDav.h OrthancServer/Sources/ResourceFinder.h
diffstat 4 files changed, 169 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Sources/OrthancFindRequestHandler.cpp	Fri Jul 12 14:08:31 2024 +0200
+++ b/OrthancServer/Sources/OrthancFindRequestHandler.cpp	Fri Jul 12 15:02:59 2024 +0200
@@ -336,32 +336,21 @@
     {
     private:
       DicomFindAnswers&           answers_;
-      ServerContext&              context_;
-      ResourceType                level_;
-      const DicomMap&             query_;
       DicomArray                  queryAsArray_;
       const std::list<DicomTag>&  sequencesToReturn_;
       std::string                 defaultPrivateCreator_;       // the private creator to use if the group is not defined in the query itself
       const std::map<uint16_t, std::string>& privateCreators_;  // the private creators defined in the query itself
       std::string                 retrieveAet_;
-      FindStorageAccessMode       findStorageAccessMode_;
 
     public:
-      LookupVisitorV2(DicomFindAnswers&  answers,
-                      ServerContext& context,
-                      ResourceType level,
+      LookupVisitorV2(DicomFindAnswers& answers,
                       const DicomMap& query,
                       const std::list<DicomTag>& sequencesToReturn,
-                      const std::map<uint16_t, std::string>& privateCreators,
-                      FindStorageAccessMode findStorageAccessMode) :
+                      const std::map<uint16_t, std::string>& privateCreators) :
         answers_(answers),
-        context_(context),
-        level_(level),
-        query_(query),
         queryAsArray_(query),
         sequencesToReturn_(sequencesToReturn),
-        privateCreators_(privateCreators),
-        findStorageAccessMode_(findStorageAccessMode)
+        privateCreators_(privateCreators)
       {
         answers_.SetComplete(false);
 
@@ -647,7 +636,7 @@
       finder.SetDatabaseLookup(lookup);
       finder.AddRequestedTags(requestedTags);
 
-      LookupVisitorV2 visitor(answers, context_, level, *filteredInput, sequencesToReturn, privateCreators, context_.GetFindStorageAccessMode());
+      LookupVisitorV2 visitor(answers, *filteredInput, sequencesToReturn, privateCreators);
       finder.Execute(visitor, context_);
     }
     else
--- a/OrthancServer/Sources/OrthancWebDav.cpp	Fri Jul 12 14:08:31 2024 +0200
+++ b/OrthancServer/Sources/OrthancWebDav.cpp	Fri Jul 12 15:02:59 2024 +0200
@@ -28,6 +28,7 @@
 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 #include "../../OrthancFramework/Sources/HttpServer/WebDavStorage.h"
 #include "../../OrthancFramework/Sources/Logging.h"
+#include "ResourceFinder.h"
 #include "Search/DatabaseLookup.h"
 #include "ServerContext.h"
 
@@ -50,6 +51,20 @@
   {
     return boost::posix_time::second_clock::universal_time();
   }
+
+
+  static void ParseTime(boost::posix_time::ptime& target,
+                        const std::string& value)
+  {
+    try
+    {
+      target = boost::posix_time::from_iso_string(value);
+    }
+    catch (std::exception& e)
+    {
+      target = GetNow();
+    }
+  }
   
 
   static void LookupTime(boost::posix_time::ptime& target,
@@ -62,17 +77,12 @@
     int64_t revision;  // Ignored
     if (context.GetIndex().LookupMetadata(value, revision, publicId, level, metadata))
     {
-      try
-      {
-        target = boost::posix_time::from_iso_string(value);
-        return;
-      }
-      catch (std::exception& e)
-      {
-      }
+      ParseTime(target, value);
     }
-
-    target = GetNow();
+    else
+    {
+      target = GetNow();
+    }
   }
 
   
@@ -169,6 +179,98 @@
   };
 
   
+  class OrthancWebDav::DicomIdentifiersVisitorV2 : public ResourceFinder::IVisitor
+  {
+  private:
+    bool         isComplete_;
+    Collection&  target_;
+
+  public:
+    DicomIdentifiersVisitorV2(Collection& target) :
+      isComplete_(false),
+      target_(target)
+    {
+    }
+
+    virtual void MarkAsComplete() ORTHANC_OVERRIDE
+    {
+      isComplete_ = true;  // TODO
+    }
+
+    virtual void Apply(const FindResponse::Resource& resource,
+                       const DicomMap& requestedTags)  ORTHANC_OVERRIDE
+    {
+      DicomMap resourceTags;
+      resource.GetMainDicomTags(resourceTags, resource.GetLevel());
+
+      std::string uid;
+      bool hasUid;
+
+      std::string time;
+      bool hasTime;
+
+      switch (resource.GetLevel())
+      {
+        case ResourceType_Study:
+          hasUid = resourceTags.LookupStringValue(uid, DICOM_TAG_STUDY_INSTANCE_UID, false);
+          hasTime = resource.LookupMetadata(time, resource.GetLevel(), MetadataType_LastUpdate);
+          break;
+
+        case ResourceType_Series:
+          hasUid = resourceTags.LookupStringValue(uid, DICOM_TAG_SERIES_INSTANCE_UID, false);
+          hasTime = resource.LookupMetadata(time, resource.GetLevel(), MetadataType_LastUpdate);
+          break;
+
+        case ResourceType_Instance:
+          hasUid = resourceTags.LookupStringValue(uid, DICOM_TAG_SOP_INSTANCE_UID, false);
+          hasTime = resource.LookupMetadata(time, resource.GetLevel(), MetadataType_Instance_ReceptionDate);
+          break;
+
+        default:
+          throw OrthancException(ErrorCode_InternalError);
+      }
+
+      if (hasUid &&
+          !uid.empty())
+      {
+        std::unique_ptr<Resource> item;
+
+        if (resource.GetLevel() == ResourceType_Instance)
+        {
+          FileInfo info;
+          if (resource.LookupAttachment(info, FileContentType_Dicom))
+          {
+            std::unique_ptr<File> f(new File(uid + ".dcm"));
+            f->SetMimeType(MimeType_Dicom);
+            f->SetContentLength(info.GetUncompressedSize());
+            item.reset(f.release());
+          }
+        }
+        else
+        {
+          item.reset(new Folder(uid));
+        }
+
+        if (item.get() != NULL)
+        {
+          if (hasTime)
+          {
+            boost::posix_time::ptime t;
+            ParseTime(t, time);
+            item->SetCreationTime(t);
+          }
+          else
+          {
+            item->SetCreationTime(GetNow());
+          }
+
+          target_.AddResource(item.release());
+        }
+      }
+    }
+  };
+
+
   class OrthancWebDav::DicomFileVisitor : public ServerContext::ILookupVisitor
   {
   private:
@@ -1455,9 +1557,48 @@
         return false;
       }
 
-      DicomIdentifiersVisitor visitor(context_, collection, level);
-      context_.Apply(visitor, query, level, 0 /* since */, limit);
-      
+      if (true)
+      {
+        /**
+         * EXPERIMENTAL VERSION
+         **/
+
+        ResourceFinder finder(level, false /* don't expand */);
+        finder.SetDatabaseLookup(query);
+        finder.SetRetrieveMetadata(true);
+
+        switch (level)
+        {
+          case ResourceType_Study:
+            finder.AddRequestedTag(DICOM_TAG_STUDY_INSTANCE_UID);
+            break;
+
+          case ResourceType_Series:
+            finder.AddRequestedTag(DICOM_TAG_SERIES_INSTANCE_UID);
+            break;
+
+          case ResourceType_Instance:
+            finder.AddRequestedTag(DICOM_TAG_SOP_INSTANCE_UID);
+            finder.SetRetrieveAttachments(true);
+            break;
+
+          default:
+            throw OrthancException(ErrorCode_InternalError);
+        }
+
+        DicomIdentifiersVisitorV2 visitor(collection);
+        finder.Execute(visitor, context_);
+      }
+      else
+      {
+        /**
+         * VERSION IN ORTHANC <= 1.12.4
+         **/
+
+        DicomIdentifiersVisitor visitor(context_, collection, level);
+        context_.Apply(visitor, query, level, 0 /* since */, limit);
+      }
+
       return true;
     }
     else if (path[0] == BY_PATIENTS ||
--- a/OrthancServer/Sources/OrthancWebDav.h	Fri Jul 12 14:08:31 2024 +0200
+++ b/OrthancServer/Sources/OrthancWebDav.h	Fri Jul 12 15:02:59 2024 +0200
@@ -40,6 +40,7 @@
     class DicomDeleteVisitor;
     class DicomFileVisitor;
     class DicomIdentifiersVisitor;  
+    class DicomIdentifiersVisitorV2;
     class InstancesOfSeries;
     class InternalNode;
     class ListOfResources;
--- a/OrthancServer/Sources/ResourceFinder.h	Fri Jul 12 14:08:31 2024 +0200
+++ b/OrthancServer/Sources/ResourceFinder.h	Fri Jul 12 15:02:59 2024 +0200
@@ -165,6 +165,16 @@
       request_.SetRetrieveOneInstanceIdentifier(retrieve);
     }
 
+    void SetRetrieveMetadata(bool retrieve)
+    {
+      request_.SetRetrieveMetadata(retrieve);
+    }
+
+    void SetRetrieveAttachments(bool retrieve)
+    {
+      request_.SetRetrieveAttachments(retrieve);
+    }
+
     void Execute(FindResponse& target,
                  ServerIndex& index) const;