diff OrthancServer/OrthancFindRequestHandler.cpp @ 1763:f7014cca73c7

integration db-changes->mainline
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 29 Oct 2015 12:45:20 +0100
parents e268412adcf1
children 4f01c9d73f02
line wrap: on
line diff
--- a/OrthancServer/OrthancFindRequestHandler.cpp	Fri Oct 23 17:04:22 2015 +0200
+++ b/OrthancServer/OrthancFindRequestHandler.cpp	Thu Oct 29 12:45:20 2015 +0100
@@ -33,14 +33,12 @@
 #include "PrecompiledHeadersServer.h"
 #include "OrthancFindRequestHandler.h"
 
+#include "../Core/DicomFormat/DicomArray.h"
 #include "../Core/Logging.h"
-#include "../Core/DicomFormat/DicomArray.h"
-#include "ServerToolbox.h"
+#include "FromDcmtkBridge.h"
 #include "OrthancInitialization.h"
-#include "FromDcmtkBridge.h"
-
-#include "ResourceFinder.h"
-#include "DicomFindQuery.h"
+#include "Search/LookupResource.h"
+#include "ServerToolbox.h"
 
 #include <boost/regex.hpp> 
 
@@ -90,130 +88,6 @@
   }
 
 
-  namespace
-  {
-    class CFindQuery : public DicomFindQuery
-    {
-    private:
-      DicomFindAnswers&      answers_;
-      ServerIndex&           index_;
-      const DicomArray&      query_;
-      bool                   hasModalitiesInStudy_;
-      std::set<std::string>  modalitiesInStudy_;
-
-    public:
-      CFindQuery(DicomFindAnswers& answers,
-                 ServerIndex& index,
-                 const DicomArray& query) :
-        answers_(answers),
-        index_(index),
-        query_(query),
-        hasModalitiesInStudy_(false)
-      {
-      }
-
-      void SetModalitiesInStudy(const std::string& value)
-      {
-        hasModalitiesInStudy_ = true;
-        
-        std::vector<std::string>  tmp;
-        Toolbox::TokenizeString(tmp, value, '\\'); 
-
-        for (size_t i = 0; i < tmp.size(); i++)
-        {
-          modalitiesInStudy_.insert(tmp[i]);
-        }
-      }
-
-      virtual bool HasMainDicomTagsFilter(ResourceType level) const
-      {
-        if (DicomFindQuery::HasMainDicomTagsFilter(level))
-        {
-          return true;
-        }
-
-        return (level == ResourceType_Study &&
-                hasModalitiesInStudy_);
-      }
-
-      virtual bool FilterMainDicomTags(const std::string& resourceId,
-                                       ResourceType level,
-                                       const DicomMap& mainTags) const
-      {
-        if (!DicomFindQuery::FilterMainDicomTags(resourceId, level, mainTags))
-        {
-          return false;
-        }
-
-        if (level != ResourceType_Study ||
-            !hasModalitiesInStudy_)
-        {
-          return true;
-        }
-
-        try
-        {
-          // We are considering a single study, and the
-          // "MODALITIES_IN_STUDY" tag is set in the C-Find. Check
-          // whether one of its child series matches one of the
-          // modalities.
-
-          Json::Value study;
-          if (index_.LookupResource(study, resourceId, ResourceType_Study))
-          {
-            // Loop over the series of the considered study.
-            for (Json::Value::ArrayIndex j = 0; j < study["Series"].size(); j++)
-            {
-              Json::Value series;
-              if (index_.LookupResource(series, study["Series"][j].asString(), ResourceType_Series))
-              {
-                // Get the modality of this series
-                if (series["MainDicomTags"].isMember("Modality"))
-                {
-                  std::string modality = series["MainDicomTags"]["Modality"].asString();
-                  if (modalitiesInStudy_.find(modality) != modalitiesInStudy_.end())
-                  {
-                    // This series of the considered study matches one
-                    // of the required modalities. Take the study into
-                    // consideration for future filtering.
-                    return true;
-                  }
-                }
-              }
-            }
-          }
-        }
-        catch (OrthancException&)
-        {
-          // This resource has probably been deleted during the find request
-        }
-
-        return false;
-      }
-
-      virtual bool HasInstanceFilter() const
-      {
-        return true;
-      }
-
-      virtual bool FilterInstance(const std::string& instanceId,
-                                  const Json::Value& content) const
-      {
-        bool ok = DicomFindQuery::FilterInstance(instanceId, content);
-
-        if (ok)
-        {
-          // Add this resource to the answers
-          AddAnswer(answers_, content, query_);
-        }
-
-        return ok;
-      }
-    };
-  }
-
-
-
   bool OrthancFindRequestHandler::Handle(DicomFindAnswers& answers,
                                          const DicomMap& input,
                                          const std::string& remoteIp,
@@ -276,9 +150,8 @@
      * Build up the query object.
      **/
 
-    CFindQuery findQuery(answers, context_.GetIndex(), query);
-    findQuery.SetLevel(level);
-        
+    LookupResource finder(level);
+
     for (size_t i = 0; i < query.GetSize(); i++)
     {
       const DicomTag tag = query.GetElement(i).GetTag();
@@ -297,14 +170,17 @@
         continue;
       }
 
-      if (tag == DICOM_TAG_MODALITIES_IN_STUDY)
+      ValueRepresentation vr = FromDcmtkBridge::GetValueRepresentation(tag);
+
+      // DICOM specifies that searches must be case sensitive, except
+      // for tags with a PN value representation
+      bool sensitive = true;
+      if (vr == ValueRepresentation_PatientName)
       {
-        findQuery.SetModalitiesInStudy(value);
+        sensitive = caseSensitivePN;
       }
-      else
-      {
-        findQuery.SetConstraint(tag, value, caseSensitivePN);
-      }
+
+      finder.AddDicomConstraint(tag, value, sensitive);
     }
 
 
@@ -312,28 +188,35 @@
      * Run the query.
      **/
 
-    ResourceFinder finder(context_);
+    size_t maxResults = (level == ResourceType_Instance) ? maxInstances_ : maxResults_;
+
+    std::vector<std::string> resources, instances;
+    context_.GetIndex().FindCandidates(resources, instances, finder);
 
-    switch (level)
+    assert(resources.size() == instances.size());
+    bool finished = true;
+
+    for (size_t i = 0; i < instances.size(); i++)
     {
-      case ResourceType_Patient:
-      case ResourceType_Study:
-      case ResourceType_Series:
-        finder.SetMaxResults(maxResults_);
-        break;
-
-      case ResourceType_Instance:
-        finder.SetMaxResults(maxInstances_);
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_InternalError);
+      Json::Value dicom;
+      context_.ReadJson(dicom, instances[i]);
+      
+      if (finder.IsMatch(dicom))
+      {
+        if (maxResults != 0 &&
+            answers.GetSize() >= maxResults)
+        {
+          finished = false;
+          break;
+        }
+        else
+        {
+          AddAnswer(answers, dicom, query);
+        }
+      }
     }
 
-    std::list<std::string> tmp;
-    bool finished = finder.Apply(tmp, findQuery);
-
-    LOG(INFO) << "Number of matching resources: " << tmp.size();
+    LOG(INFO) << "Number of matching resources: " << answers.GetSize();
 
     return finished;
   }