changeset 213:4ce7fdcc8879

access to tags, simplified-tags and file of an instance
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 29 Nov 2012 10:59:40 +0100
parents f276b175dcaf
children 03817919169b
files CMakeLists.txt OrthancServer/OrthancRestApi.cpp OrthancServer/OrthancRestApi2.cpp OrthancServer/OrthancRestApi2.h OrthancServer/ServerToolbox.cpp OrthancServer/ServerToolbox.h
diffstat 6 files changed, 213 insertions(+), 132 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Thu Nov 29 10:13:49 2012 +0100
+++ b/CMakeLists.txt	Thu Nov 29 10:59:40 2012 +0100
@@ -145,6 +145,7 @@
   OrthancServer/ToDcmtkBridge.cpp
   OrthancServer/DatabaseWrapper.cpp
   OrthancServer/ServerEnumerations.cpp
+  OrthancServer/ServerToolbox.cpp
   )
 
 # Ensure autogenerated code is built before building ServerLibrary
--- a/OrthancServer/OrthancRestApi.cpp	Thu Nov 29 10:13:49 2012 +0100
+++ b/OrthancServer/OrthancRestApi.cpp	Thu Nov 29 10:59:40 2012 +0100
@@ -34,6 +34,7 @@
 
 #include "OrthancInitialization.h"
 #include "FromDcmtkBridge.h"
+#include "ServerToolbox.h"
 #include "../Core/Uuid.h"
 #include "../Core/HttpServer/FilesystemHttpSender.h"
 
@@ -51,71 +52,6 @@
     output.AnswerBufferWithContentType(s, "application/json");
   }
 
-
-  static void SimplifyTagsRecursion(Json::Value& target,
-                                    const Json::Value& source)
-  {
-    assert(source.isObject());
-
-    target = Json::objectValue;
-    Json::Value::Members members = source.getMemberNames();
-
-    for (size_t i = 0; i < members.size(); i++)
-    {
-      const Json::Value& v = source[members[i]];
-      const std::string& name = v["Name"].asString();
-      const std::string& type = v["Type"].asString();
-
-      if (type == "String")
-      {
-        target[name] = v["Value"].asString();
-      }
-      else if (type == "TooLong" ||
-               type == "Null")
-      {
-        target[name] = Json::nullValue;
-      }
-      else if (type == "Sequence")
-      {
-        const Json::Value& array = v["Value"];
-        assert(array.isArray());
-
-        Json::Value children = Json::arrayValue;
-        for (Json::Value::ArrayIndex i = 0; i < array.size(); i++)
-        {
-          Json::Value c;
-          SimplifyTagsRecursion(c, array[i]);
-          children.append(c);
-        }
-
-        target[name] = children;
-      }
-      else
-      {
-        assert(0);
-      }
-    }
-  }
-
-
-  static void SimplifyTags(Json::Value& target,
-                           const FileStorage& storage,
-                           const std::string& fileUuid)
-  {
-    std::string s;
-    storage.ReadFile(s, fileUuid);
-
-    Json::Value source;
-    Json::Reader reader;
-    if (!reader.parse(s, source))
-    {
-      throw OrthancException("Corrupted JSON file");
-    }
-
-    SimplifyTagsRecursion(target, source);
-  }
-
-
   bool OrthancRestApi::Store(Json::Value& result,
                                const std::string& postData)
   {
@@ -437,69 +373,6 @@
     }
 
 
-    // Information about a single object ----------------------------------------
- 
-    else if (uri.size() == 2 && 
-             (uri[0] == "instances" ||
-              uri[0] == "series" ||
-              uri[0] == "studies" ||
-              uri[0] == "patients"))
-    {
-      if (method == "GET")
-      {
-        if (uri[0] == "patients")
-        {
-          existingResource = index_.LookupResource(result, uri[1], ResourceType_Patient);
-          assert(!existingResource || result["Type"] == "Patient");
-        }
-        else if (uri[0] == "studies")
-        {
-          existingResource = index_.LookupResource(result, uri[1], ResourceType_Study);
-          assert(!existingResource || result["Type"] == "Study");
-        }
-        else if (uri[0] == "series")
-        {
-          existingResource = index_.LookupResource(result, uri[1], ResourceType_Series);
-          assert(!existingResource || result["Type"] == "Series");
-        }
-        else if (uri[0] == "instances")
-        {
-          existingResource = index_.LookupResource(result, uri[1], ResourceType_Instance);
-          assert(!existingResource || result["Type"] == "Instance");
-        }
-      }
-      else if (method == "DELETE")
-      {
-        if (uri[0] == "patients")
-        {
-          existingResource = index_.DeleteResource(result, uri[1], ResourceType_Patient);
-        }
-        else if (uri[0] == "studies")
-        {
-          existingResource = index_.DeleteResource(result, uri[1], ResourceType_Study);
-        }
-        else if (uri[0] == "series")
-        {
-          existingResource = index_.DeleteResource(result, uri[1], ResourceType_Series);
-        }
-        else if (uri[0] == "instances")
-        {
-          existingResource = index_.DeleteResource(result, uri[1], ResourceType_Instance);
-        }
-
-        if (existingResource)
-        {
-          result["Status"] = "Success";
-        }
-      }
-      else
-      {
-        output.SendMethodNotAllowedError("GET,DELETE");
-        return;
-      }
-    }
-
-
     // Get the DICOM or the JSON file of one instance ---------------------------
  
     else if (uri.size() == 3 &&
@@ -528,9 +401,10 @@
       {
         if (uri[2] == "simplified-tags")
         {
-          Json::Value v;
-          SimplifyTags(v, storage_, fileUuid);
-          SendJson(output, v);
+          Json::Value simplified, full;
+          ReadJson(full, storage_, fileUuid);
+          SimplifyTags(simplified, full);
+          SendJson(output, simplified);
           return;
         }
         else
--- a/OrthancServer/OrthancRestApi2.cpp	Thu Nov 29 10:13:49 2012 +0100
+++ b/OrthancServer/OrthancRestApi2.cpp	Thu Nov 29 10:59:40 2012 +0100
@@ -36,6 +36,7 @@
 #include "FromDcmtkBridge.h"
 #include "../Core/Uuid.h"
 #include "../Core/HttpServer/FilesystemHttpSender.h"
+#include "ServerToolbox.h"
 
 #include <dcmtk/dcmdata/dcistrmb.h>
 #include <dcmtk/dcmdata/dcfilefo.h>
@@ -141,6 +142,58 @@
 
 
   
+  // Get information about a single instance ----------------------------------
+ 
+  static void GetInstanceFile(RestApi::GetCall& call)
+  {
+    RETRIEVE_CONTEXT(call);
+
+    CompressionType compressionType;
+    std::string fileUuid;
+    std::string publicId = call.GetUriComponent("id", "");
+
+    if (context.GetIndex().GetFile(fileUuid, compressionType, publicId, AttachedFileType_Dicom))
+    {
+      assert(compressionType == CompressionType_None);
+
+      FilesystemHttpSender sender(context.GetFileStorage(), fileUuid);
+      sender.SetFilename(fileUuid + ".dcm");
+      sender.SetContentType("application/dicom");
+      call.GetOutput().AnswerFile(sender);
+    }
+  }
+
+
+  template <bool simplify>
+  static void GetInstanceTags(RestApi::GetCall& call)
+  {
+    RETRIEVE_CONTEXT(call);
+
+    CompressionType compressionType;
+    std::string fileUuid;
+    std::string publicId = call.GetUriComponent("id", "");
+
+    if (context.GetIndex().GetFile(fileUuid, compressionType, publicId, AttachedFileType_Json))
+    {
+      assert(compressionType == CompressionType_None);
+
+      Json::Value full;
+      ReadJson(full, context.GetFileStorage(), fileUuid);
+
+      if (simplify)
+      {
+        Json::Value simplified;
+        SimplifyTags(simplified, full);
+        call.GetOutput().AnswerJson(simplified);
+      }
+      else
+      {
+        call.GetOutput().AnswerJson(full);
+      }
+    }
+  }
+
+
 
   // DICOM bridge -------------------------------------------------------------
 
@@ -161,6 +214,9 @@
   }
 
 
+
+  // Registration of the various REST handlers --------------------------------
+
   OrthancRestApi2::OrthancRestApi2(ServerIndex& index,
                                    const std::string& path) :
     index_(index),
@@ -186,5 +242,11 @@
     Register("/series/{id}", GetSingleResource<ResourceType_Series>);
     Register("/studies/{id}", DeleteSingleResource<ResourceType_Study>);
     Register("/studies/{id}", GetSingleResource<ResourceType_Study>);
+
+    Register("/instances/{id}/file", GetInstanceFile);
+    Register("/instances/{id}/tags", GetInstanceTags<false>);
+    Register("/instances/{id}/simplified-tags", GetInstanceTags<true>);
+
+    // TODO : "content", "frames"
   }
 }
--- a/OrthancServer/OrthancRestApi2.h	Thu Nov 29 10:13:49 2012 +0100
+++ b/OrthancServer/OrthancRestApi2.h	Thu Nov 29 10:59:40 2012 +0100
@@ -58,7 +58,7 @@
       return index_;
     }
     
-    FileStorage& GetStorage()
+    FileStorage& GetFileStorage()
     {
       return storage_;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/ServerToolbox.cpp	Thu Nov 29 10:59:40 2012 +0100
@@ -0,0 +1,97 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012 Medical Physics Department, CHU of Liege,
+ * Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "ServerToolbox.h"
+
+#include "../Core/OrthancException.h"
+
+namespace Orthanc
+{
+  void ReadJson(Json::Value& target,
+                const FileStorage& storage,
+                const std::string& fileUuid)
+  {
+    std::string s;
+    storage.ReadFile(s, fileUuid);
+
+    Json::Reader reader;
+    if (!reader.parse(s, target))
+    {
+      throw OrthancException("Corrupted JSON file");
+    }
+  }
+
+  void SimplifyTags(Json::Value& target,
+                    const Json::Value& source)
+  {
+    assert(source.isObject());
+
+    target = Json::objectValue;
+    Json::Value::Members members = source.getMemberNames();
+
+    for (size_t i = 0; i < members.size(); i++)
+    {
+      const Json::Value& v = source[members[i]];
+      const std::string& name = v["Name"].asString();
+      const std::string& type = v["Type"].asString();
+
+      if (type == "String")
+      {
+        target[name] = v["Value"].asString();
+      }
+      else if (type == "TooLong" ||
+               type == "Null")
+      {
+        target[name] = Json::nullValue;
+      }
+      else if (type == "Sequence")
+      {
+        const Json::Value& array = v["Value"];
+        assert(array.isArray());
+
+        Json::Value children = Json::arrayValue;
+        for (Json::Value::ArrayIndex i = 0; i < array.size(); i++)
+        {
+          Json::Value c;
+          SimplifyTags(c, array[i]);
+          children.append(c);
+        }
+
+        target[name] = children;
+      }
+      else
+      {
+        assert(0);
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/ServerToolbox.h	Thu Nov 29 10:59:40 2012 +0100
@@ -0,0 +1,47 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012 Medical Physics Department, CHU of Liege,
+ * Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "../Core/FileStorage.h"
+
+#include <json/json.h>
+
+namespace Orthanc
+{
+  void ReadJson(Json::Value& target,
+                const FileStorage& storage,
+                const std::string& fileUuid);
+
+  void SimplifyTags(Json::Value& target,
+                    const Json::Value& source);
+}