# HG changeset patch # User Sebastien Jodogne # Date 1405696534 -7200 # Node ID 00f9f36bcd94b2f2159c607873595102760525b3 # Parent 0bfeeb6d340f8a96a7d86ab2d82c9c808cb5bfe2 on-the-fly conversion of JSON to XML according to HTTP Accept diff -r 0bfeeb6d340f -r 00f9f36bcd94 CMakeLists.txt --- 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)") diff -r 0bfeeb6d340f -r 00f9f36bcd94 Core/RestApi/RestApi.cpp --- 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 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; } diff -r 0bfeeb6d340f -r 00f9f36bcd94 Core/RestApi/RestApiOutput.cpp --- 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; } diff -r 0bfeeb6d340f -r 00f9f36bcd94 Core/RestApi/RestApiOutput.h --- 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); diff -r 0bfeeb6d340f -r 00f9f36bcd94 INSTALL --- 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. diff -r 0bfeeb6d340f -r 00f9f36bcd94 LinuxCompilation.txt --- 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