changeset 1046:00f9f36bcd94

on-the-fly conversion of JSON to XML according to HTTP Accept
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 18 Jul 2014 17:15:34 +0200
parents 0bfeeb6d340f
children 16609969f319
files CMakeLists.txt Core/RestApi/RestApi.cpp Core/RestApi/RestApiOutput.cpp Core/RestApi/RestApiOutput.h INSTALL LinuxCompilation.txt
diffstat 6 files changed, 75 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Fri Jul 18 16:41:10 2014 +0200
+++ b/CMakeLists.txt	Fri Jul 18 17:15:34 2014 +0200
@@ -34,12 +34,12 @@
 SET(USE_SYSTEM_CURL ON CACHE BOOL "Use the system version of LibCurl")
 SET(USE_SYSTEM_OPENSSL ON CACHE BOOL "Use the system version of OpenSSL")
 SET(USE_SYSTEM_ZLIB ON CACHE BOOL "Use the system version of ZLib")
+SET(USE_SYSTEM_PUGIXML ON CACHE BOOL "Use the system version of Pugixml)")
 
 # Experimental options
 SET(USE_PLUSTACHE OFF CACHE BOOL "Use the Plustache templating engine (experimental)")
-SET(USE_PUGIXML OFF CACHE BOOL "Use the Pugixml parser (experimental)")
+SET(USE_PUGIXML ON CACHE BOOL "Use the Pugixml parser (turn off only for debug)")
 SET(USE_SYSTEM_PLUSTACHE OFF CACHE BOOL "Use the system version of Plustache (experimental)")
-SET(USE_SYSTEM_PUGIXML OFF CACHE BOOL "Use the system version of Pugixml (experimental)")
 
 # Distribution-specific settings
 SET(USE_GTEST_DEBIAN_SOURCE_PACKAGE OFF CACHE BOOL "Use the sources of Google Test shipped with libgtest-dev (Debian only)")
--- a/Core/RestApi/RestApi.cpp	Fri Jul 18 16:41:10 2014 +0200
+++ b/Core/RestApi/RestApi.cpp	Fri Jul 18 17:15:34 2014 +0200
@@ -47,7 +47,7 @@
     {
     private:
       RestApi& api_;
-      HttpOutput& output_;
+      RestApiOutput& output_;
       HttpMethod method_;
       const HttpHandler::Arguments& headers_;
       const HttpHandler::Arguments& getArguments_;
@@ -55,7 +55,7 @@
 
     public:
       HttpHandlerVisitor(RestApi& api,
-                         HttpOutput& output,
+                         RestApiOutput& output,
                          HttpMethod method,
                          const HttpHandler::Arguments& headers,
                          const HttpHandler::Arguments& getArguments,
@@ -76,34 +76,32 @@
       {
         if (resource.HasHandler(method_))
         {
-          RestApiOutput output(output_);
-
           switch (method_)
           {
             case HttpMethod_Get:
             {
-              RestApiGetCall call(output, api_, headers_, components, trailing, uri, getArguments_);
+              RestApiGetCall call(output_, api_, headers_, components, trailing, uri, getArguments_);
               resource.Handle(call);
               return true;
             }
 
             case HttpMethod_Post:
             {
-              RestApiPostCall call(output, api_, headers_, components, trailing, uri, postData_);
+              RestApiPostCall call(output_, api_, headers_, components, trailing, uri, postData_);
               resource.Handle(call);
               return true;
             }
 
             case HttpMethod_Delete:
             {
-              RestApiDeleteCall call(output, api_, headers_, components, trailing, uri);
+              RestApiDeleteCall call(output_, api_, headers_, components, trailing, uri);
               resource.Handle(call);
               return true;
             }
 
             case HttpMethod_Put:
             {
-              RestApiPutCall call(output, api_, headers_, components, trailing, uri, postData_);
+              RestApiPutCall call(output_, api_, headers_, components, trailing, uri, postData_);
               resource.Handle(call);
               return true;
             }
@@ -165,7 +163,32 @@
                        const Arguments& getArguments,
                        const std::string& postData)
   {
-    HttpHandlerVisitor visitor(*this, output, method, headers, getArguments, postData);
+    RestApiOutput wrappedOutput(output);
+
+#if ORTHANC_PUGIXML_ENABLED == 1
+    // Look if the user wishes XML answers instead of JSON
+    // http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#z3
+    Arguments::const_iterator it = headers.find("accept");
+    if (it != headers.end())
+    {
+      std::vector<std::string> accepted;
+      Toolbox::TokenizeString(accepted, it->second, ';');
+      for (size_t i = 0; i < accepted.size(); i++)
+      {
+        if (accepted[i] == "application/xml")
+        {
+          wrappedOutput.SetConvertJsonToXml(true);
+        }
+
+        if (accepted[i] == "application/json")
+        {
+          wrappedOutput.SetConvertJsonToXml(false);
+        }
+      }
+    }
+#endif
+
+    HttpHandlerVisitor visitor(*this, wrappedOutput, method, headers, getArguments, postData);
 
     if (root_.LookupResource(uri, visitor))
     {
@@ -175,8 +198,7 @@
     Json::Value directory;
     if (root_.GetDirectory(directory, uri))
     {
-      RestApiOutput tmp(output);
-      tmp.AnswerJson(directory);
+      wrappedOutput.AnswerJson(directory);
       return true;
     }
 
--- a/Core/RestApi/RestApiOutput.cpp	Fri Jul 18 16:41:10 2014 +0200
+++ b/Core/RestApi/RestApiOutput.cpp	Fri Jul 18 17:15:34 2014 +0200
@@ -40,7 +40,8 @@
 namespace Orthanc
 {
   RestApiOutput::RestApiOutput(HttpOutput& output) : 
-    output_(output)
+    output_(output),
+    convertJsonToXml_(false)
   {
     alreadySent_ = false;
   }
@@ -71,9 +72,25 @@
   void RestApiOutput::AnswerJson(const Json::Value& value)
   {
     CheckStatus();
-    Json::StyledWriter writer;
-    std::string s = writer.write(value);
-    output_.AnswerBufferWithContentType(s, "application/json");
+
+    if (convertJsonToXml_)
+    {
+#if ORTHANC_PUGIXML_ENABLED == 1
+      std::string s;
+      Toolbox::JsonToXml(s, value);
+      output_.AnswerBufferWithContentType(s, "application/xml");
+#else
+      LOG(ERROR) << "Orthanc was compiled without XML support";
+      throw OrthancException(ErrorCode_InternalError);
+#endif
+    }
+    else
+    {
+      Json::StyledWriter writer;
+      std::string s = writer.write(value);
+      output_.AnswerBufferWithContentType(s, "application/json");
+    }
+
     alreadySent_ = true;
   }
 
--- a/Core/RestApi/RestApiOutput.h	Fri Jul 18 16:41:10 2014 +0200
+++ b/Core/RestApi/RestApiOutput.h	Fri Jul 18 17:15:34 2014 +0200
@@ -44,6 +44,7 @@
   private:
     HttpOutput& output_;
     bool alreadySent_;
+    bool convertJsonToXml_;
 
     void CheckStatus();
 
@@ -62,6 +63,16 @@
       alreadySent_ = true;
     }
 
+    void SetConvertJsonToXml(bool convert)
+    {
+      convertJsonToXml_ = convert;
+    }
+
+    bool IsConvertJsonToXml() const
+    {
+      return convertJsonToXml_;
+    }
+
     void AnswerFile(HttpFileSender& sender);
 
     void AnswerJson(const Json::Value& value);
--- a/INSTALL	Fri Jul 18 16:41:10 2014 +0200
+++ b/INSTALL	Fri Jul 18 17:15:34 2014 +0200
@@ -58,7 +58,7 @@
 ------------------------------------------------------
 
 # cd [...]\OrthancBuild
-# cmake -DSTANDALONE_BUILD=ON -G "Visual Studio 8 2005" [...]\Orthanc
+# cmake -DSTANDALONE_BUILD=ON -DSTATIC_BUILD=ON -G "Visual Studio 8 2005" [...]\Orthanc
 
 Then open the "[...]/OrthancBuild/Orthanc.sln" with Visual Studio.
 
--- a/LinuxCompilation.txt	Fri Jul 18 16:41:10 2014 +0200
+++ b/LinuxCompilation.txt	Fri Jul 18 17:15:34 2014 +0200
@@ -77,6 +77,7 @@
 	-DUSE_SYSTEM_DCMTK=OFF \
 	-DUSE_SYSTEM_MONGOOSE=OFF \
 	-DUSE_SYSTEM_JSONCPP=OFF \
+	-DUSE_SYSTEM_PUGIXML=OFF \
         -DENABLE_JPEG=OFF \
         -DENABLE_JPEG_LOSSLESS=OFF \
 	~/Orthanc 
@@ -95,6 +96,7 @@
         -DUSE_SYSTEM_GOOGLE_LOG=OFF \
 	-DUSE_SYSTEM_MONGOOSE=OFF \
         -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+	-DUSE_SYSTEM_PUGIXML=OFF \
         -DENABLE_JPEG=OFF \
         -DENABLE_JPEG_LOSSLESS=OFF \
 	~/Orthanc
@@ -112,6 +114,7 @@
 # cmake -DALLOW_DOWNLOADS=ON \
 	-DUSE_SYSTEM_MONGOOSE=OFF \
         -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+	-DUSE_SYSTEM_PUGIXML=OFF \
         -DENABLE_JPEG=OFF \
         -DENABLE_JPEG_LOSSLESS=OFF \
 	~/Orthanc
@@ -133,6 +136,7 @@
 	-DUSE_SYSTEM_MONGOOSE=OFF \
 	-DUSE_SYSTEM_JSONCPP=OFF \
 	-DUSE_SYSTEM_GOOGLE_LOG=OFF \
+	-DUSE_SYSTEM_PUGIXML=OFF \
         -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
         -DENABLE_JPEG=OFF \
         -DENABLE_JPEG_LOSSLESS=OFF \
@@ -155,6 +159,7 @@
 	-DUSE_SYSTEM_MONGOOSE=OFF \
 	-DUSE_SYSTEM_JSONCPP=OFF \
         -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+	-DUSE_SYSTEM_PUGIXML=OFF \
 	~/Orthanc
 
 
@@ -165,6 +170,7 @@
 	-DUSE_SYSTEM_MONGOOSE=OFF \
 	-DUSE_SYSTEM_JSONCPP=OFF \
         -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+	-DUSE_SYSTEM_PUGIXML=OFF \
         -DENABLE_JPEG=OFF \
         -DENABLE_JPEG_LOSSLESS=OFF \
 	~/Orthanc
@@ -183,6 +189,7 @@
         -DALLOW_DOWNLOADS=ON \
 	-DUSE_SYSTEM_MONGOOSE=OFF \
         -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+	-DUSE_SYSTEM_PUGIXML=OFF \
         -DENABLE_JPEG=OFF \
         -DENABLE_JPEG_LOSSLESS=OFF \
 	~/Orthanc