diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FileFinder.h b/Code/Mantid/Framework/API/inc/MantidAPI/FileFinder.h index 38d8f613f969eae9b32049488d1f50be36cd24e2..b334f756a323fcca3dda575d21ce68118d4788a1 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/FileFinder.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/FileFinder.h @@ -71,7 +71,8 @@ namespace Mantid FileFinderImpl& operator=(const FileFinderImpl&); std::string extractAllowedSuffix(std::string & userString) const; std::pair<std::string,std::string> toInstrumentAndNumber(const std::string& hint)const; - std::string getArchivePath(const std::vector<IArchiveSearch_sptr>& archs, const std::string& fName)const; + std::string getArchivePath(const std::vector<IArchiveSearch_sptr>& archs, const std::set<std::string>& filenames, const std::vector<std::string>& exts)const; + std::string toUpper(const std::string &src) const; /// glob option - set to case sensitive or insensitive int globOption; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IArchiveSearch.h b/Code/Mantid/Framework/API/inc/MantidAPI/IArchiveSearch.h index 59f78621a4f71cd84f8c1df9ce2bec4ad9e1aeab..757955f3e8a9197f358c52060c64a85497a0c81e 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IArchiveSearch.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IArchiveSearch.h @@ -8,6 +8,9 @@ #include <boost/shared_ptr.hpp> #include <string> +#include <vector> +#include <set> + #define DECLARE_ARCHIVESEARCH(classname,facility) \ namespace { \ @@ -56,11 +59,11 @@ namespace Mantid * Return the full path to a data file in an archive * @param fName :: The file name */ - virtual std::string getPath(const std::string& fName)const = 0; + virtual std::string getArchivePath(const std::set<std::string>& filenames, const std::vector<std::string>& exts)const = 0; }; - ///Typedef for a shared pointer to an IArchiveSearch - typedef boost::shared_ptr<IArchiveSearch> IArchiveSearch_sptr; + ///Typedef for a shared pointer to an IArchiveSearch + typedef boost::shared_ptr<IArchiveSearch> IArchiveSearch_sptr; } } diff --git a/Code/Mantid/Framework/API/src/FileFinder.cpp b/Code/Mantid/Framework/API/src/FileFinder.cpp index 57582e00f0a02489adfe1cb38b7e5c61e5669925..8f990c8796f8037c560728d1fb01825d7c229a37 100644 --- a/Code/Mantid/Framework/API/src/FileFinder.cpp +++ b/Code/Mantid/Framework/API/src/FileFinder.cpp @@ -375,6 +375,13 @@ namespace Mantid // get facility from the FacilityInfo const Kernel::FacilityInfo facility = this->getFacility(hint); + // get facility extensions + const std::vector<std::string> facility_extensions = facility.extensions(); + // select allowed extensions + std::vector < std::string > extensions; + + g_log.debug() << "Add facility extensions defined in the Facility.xml file" << "\n"; + extensions.assign(facility_extensions.begin(), facility_extensions.end()); // initialize the archive searcher std::vector<IArchiveSearch_sptr> archs; @@ -397,11 +404,15 @@ namespace Mantid std::string extension; if (hintPath.depth() == 0) { - std::size_t i = filename.find_last_of('.'); - if (i != std::string::npos) + for (std::vector<std::string>::iterator it = extensions.begin() ; it != extensions.end(); ++it) { - extension = filename.substr(i); - filename.erase(i); + std::size_t found = toUpper(filename).rfind(toUpper(*it)); + if (found != std::string::npos) + { + extension = filename.substr(found); + filename.erase(found); + break; + } } try { @@ -456,13 +467,7 @@ namespace Mantid } } - // work through the extensions - const std::vector<std::string> facility_extensions = facility.extensions(); - // select allowed extensions - std::vector < std::string > extensions; - g_log.debug() << "Add facility extensions defined in the Facility.xml file" << "\n"; - extensions.assign(facility_extensions.begin(), facility_extensions.end()); std::string path = getPath(archs, filenames, extensions); if (!path.empty()) { @@ -583,16 +588,15 @@ namespace Mantid * @return The full path if the file exists and can be found in one of the search locations * or an empty string otherwise. */ - std::string FileFinderImpl::getArchivePath(const std::vector<IArchiveSearch_sptr>& archs, const std::string& fName) const + std::string FileFinderImpl::getArchivePath(const std::vector<IArchiveSearch_sptr>& archs, const std::set<std::string>& filenames, const std::vector<std::string>& exts) const { - g_log.debug() << "getArchivePath(" << fName << ")\n"; std::string path = ""; std::vector<IArchiveSearch_sptr>::const_iterator it = archs.begin(); for (; it != archs.end(); ++it) { try { - path = (*it)->getPath(fName); + path = (*it)->getArchivePath(filenames, exts); if (!path.empty()) { return path; @@ -626,7 +630,7 @@ namespace Mantid Kernel::ConfigService::Instance().getDataSearchDirs(); // Before we try any globbing, make sure we exhaust all reasonable attempts at constructing the possible filename. - // Avoiding the globbing of getFullPath() for as long as possible will help performance when calling findRuns() + // Avoiding the globbing of getFullPath() for as long as possible will help performance when calling findRuns() // with a large range of files, especially when searchPaths consists of folders containing a large number of runs. for(auto ext = extensions.begin(); ext != extensions.end(); ++ext) { @@ -672,33 +676,32 @@ namespace Mantid if (archs.size() != 0 ) { g_log.debug() << "Search the archive of the default facility" << "\n"; - std::string path = ""; - std::vector<std::string>::const_iterator ext = extensions.begin(); - for (; ext != extensions.end(); ++ext) + std::string path = getArchivePath(archs, filenames, exts); + try { - std::set<std::string>::const_iterator it = filenames.begin(); - for(; it!=filenames.end(); ++it) + if (!path.empty() && Poco::File(path).exists()) { - path = getArchivePath(archs, *it + *ext); - try - { - if (!path.empty() && Poco::File(path).exists()) - { - return path; - } - } - catch(std::exception& e) - { - g_log.error() << "Cannot open file " << path << ": " << e.what() << '\n'; - return ""; - } - } // it - } // ext + return path; + } + } + catch(std::exception& e) + { + g_log.error() << "Cannot open file " << path << ": " << e.what() << '\n'; + return ""; + } + } // archs return ""; } + std::string FileFinderImpl::toUpper(const std::string &src) const + { + std::string result = src; + std::transform(result.begin(),result.end(),result.begin(),toupper); + return result; + } + }// API }// Mantid diff --git a/Code/Mantid/Framework/API/test/FileFinderTest.h b/Code/Mantid/Framework/API/test/FileFinderTest.h index be4d38f7b311b9235563f583275e12c83cb52209..fc66576eb7480d0927148641773aa7a3c2d2e90d 100644 --- a/Code/Mantid/Framework/API/test/FileFinderTest.h +++ b/Code/Mantid/Framework/API/test/FileFinderTest.h @@ -242,8 +242,13 @@ public: TS_ASSERT(file.exists()); path = FileFinder::Instance().findRun("OFFSPEC4622.log"); - TS_ASSERT(path.size() > 3); - TS_ASSERT_EQUALS(path.substr(path.size() - 3), "log"); + // Per discussion with Martyn on Dec 6, 2012: we decided to update this test case. + // *.log is not a valid extension for ISIS instruments. Since we modified the FileFinder to strip + // the extension using the facility extension list rather than to strip the extension after the last dot, + // the returned path should be empty now. + TS_ASSERT(path.empty() == true); +// TS_ASSERT(path.size() > 3); +// TS_ASSERT_EQUALS(path.substr(path.size() - 3), "log"); } void testFindRunsDefaultInst() diff --git a/Code/Mantid/Framework/DataHandling/CMakeLists.txt b/Code/Mantid/Framework/DataHandling/CMakeLists.txt index 1c3d6e9c791f96182b7f10758ad9393ca176620e..733fe286a6bb1bef0f3fdaea0edc59f5fa9f5951 100644 --- a/Code/Mantid/Framework/DataHandling/CMakeLists.txt +++ b/Code/Mantid/Framework/DataHandling/CMakeLists.txt @@ -98,13 +98,13 @@ set ( SRC_FILES src/MonitorLiveData.cpp src/MoveInstrumentComponent.cpp src/NexusTester.cpp - src/OrbiterDataArchive.cpp src/ProcessDasNexusLog.cpp src/RawFileInfo.cpp src/RemoveLogs.cpp src/RenameLog.cpp src/RotateInstrumentComponent.cpp src/SNSDataArchive.cpp + src/SNSDataArchiveICAT2.cpp src/SNSLiveEventDataListener.cpp src/SaveAscii.cpp src/SaveCSV.cpp @@ -231,13 +231,13 @@ set ( INC_FILES inc/MantidDataHandling/MonitorLiveData.h inc/MantidDataHandling/MoveInstrumentComponent.h inc/MantidDataHandling/NexusTester.h - inc/MantidDataHandling/OrbiterDataArchive.h inc/MantidDataHandling/ProcessDasNexusLog.h inc/MantidDataHandling/RawFileInfo.h inc/MantidDataHandling/RemoveLogs.h inc/MantidDataHandling/RenameLog.h inc/MantidDataHandling/RotateInstrumentComponent.h inc/MantidDataHandling/SNSDataArchive.h + inc/MantidDataHandling/SNSDataArchiveICAT2.h inc/MantidDataHandling/SNSLiveEventDataListener.h inc/MantidDataHandling/SaveAscii.h inc/MantidDataHandling/SaveCSV.h @@ -356,12 +356,12 @@ set ( TEST_FILES MonitorLiveDataTest.h MoveInstrumentComponentTest.h NexusTesterTest.h - OrbiterDataArchiveTest.h ProcessDasNexusLogTest.h RawFileInfoTest.h RemoveLogsTest.h RenameLogTest.h SNSDataArchiveTest.h + SNSDataArchiveICAT2Test.h SaveAsciiTest.h SaveCSVTest.h SaveCalFileTest.h diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/ISISDataArchive.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/ISISDataArchive.h index 1361278dbed1dc4cababc8a53ee9fac4f5a91c5e..f859147764814d330d8bfa1931a29f800d7fb391 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/ISISDataArchive.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/ISISDataArchive.h @@ -11,6 +11,10 @@ namespace Mantid { +namespace Kernel +{ +class Logger; +} namespace DataHandling { @@ -43,9 +47,12 @@ namespace Mantid class DLLExport ISISDataArchive: public API::IArchiveSearch { public: + std::string getArchivePath(const std::set<std::string>& filenames, const std::vector<std::string>& exts)const; + private: + // static reference to the logger class + static Mantid::Kernel::Logger & g_log; std::string getPath(const std::string& fName)const; }; - } } diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchive.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchive.h index 241fab911629848b77a96839bd281ba465f60bd2..760497a83c820dacdc7a3a751e50789e450ee4dc 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchive.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchive.h @@ -51,7 +51,8 @@ class Logger; class DLLExport SNSDataArchive: public API::IArchiveSearch { public: - std::string getPath(const std::string& fName) const; + //std::string getPath(const std::string& fName) const; + std::string getArchivePath(const std::set<std::string>& filenames, const std::vector<std::string>& exts) const; private: // static reference to the logger class static Mantid::Kernel::Logger & g_log; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/OrbiterDataArchive.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchiveICAT2.h similarity index 76% rename from Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/OrbiterDataArchive.h rename to Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchiveICAT2.h index 15db016d56f39896b50d016424783bc9c467f599..5108b5d36ef6cafdb90ca1ff0c555c73f1f97b19 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/OrbiterDataArchive.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchiveICAT2.h @@ -1,5 +1,5 @@ -#ifndef MANTID_DATAHANDLING_ORBITERDATAARCHIVE_H_ -#define MANTID_DATAHANDLING_ORBITERDATAARCHIVE_H_ +#ifndef MANTID_DATAHANDLING_SNSDATAARCHIVEICAT2_H_ +#define MANTID_DATAHANDLING_SNSDATAARCHIVEICAT2_H_ //---------------------------------------------------------------------- // Includes @@ -22,10 +22,10 @@ class Logger; namespace DataHandling { /** - This class is for searching the Orbiter data archive + This class is for searching the SNS data archive - @author Stuart Campbell, ORNL - @date 18/03/2010 + @author Shelly Ren, ORNL + @date 02/22/2012 Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory @@ -48,16 +48,17 @@ class Logger; Code Documentation is available at: <http://doxygen.mantidproject.org> */ - class DLLExport OrbiterDataArchive: public API::IArchiveSearch + class DLLExport SNSDataArchiveICAT2: public API::IArchiveSearch { public: - std::string getPath(const std::string& fName) const; + std::string getArchivePath(const std::set<std::string>& filenames, const std::vector<std::string>& exts) const; private: // static reference to the logger class + std::string getPath(const std::string& fName) const; static Mantid::Kernel::Logger & g_log; }; } } -#endif /* MANTID_DATAHANDLING_ORBITERDATAARCHIVE_H_ */ +#endif /* MANTID_DATAHANDLING_SNSDATAARCHIVEICAT2_H_ */ diff --git a/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp b/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp index b08d2a1fa219b7ab1b12f729c219cc34627d8b38..4f88ed90f51b4fa869cb123862435b2cb7c3b616 100644 --- a/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp +++ b/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp @@ -8,6 +8,10 @@ #include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPResponse.h> #include <Poco/URI.h> +#include <Poco/Path.h> +#include <Poco/File.h> +#include <Poco/StringTokenizer.h> +#include <Poco/Exception.h> #include <iostream> @@ -21,14 +25,16 @@ namespace Mantid { namespace DataHandling { - +Mantid::Kernel::Logger & ISISDataArchive::g_log = Mantid::Kernel::Logger::get("ISISDataArchive"); DECLARE_ARCHIVESEARCH(ISISDataArchive,ISISDataSearch); + /** * Calls a web service to get a full path to a file * @param fName :: The file name. * @return The path to the file or empty string in case of error. */ + std::string ISISDataArchive::getPath(const std::string& fName)const { #ifdef _WIN32 @@ -74,5 +80,43 @@ std::string ISISDataArchive::getPath(const std::string& fName)const return out; } +std::string ISISDataArchive::getArchivePath(const std::set<std::string>& filenames, const std::vector<std::string>& exts)const +{ + std::set<std::string>::const_iterator iter = filenames.begin(); + for(; iter!=filenames.end(); ++iter) + { + g_log.debug() << *iter << ")\n"; + } + std::vector<std::string>::const_iterator iter2 = exts.begin(); + for(; iter2!=exts.end(); ++iter2) + { + g_log.debug() << *iter2 << ")\n"; + } + + std::vector<std::string>::const_iterator ext = exts.begin(); + for (; ext != exts.end(); ++ext) + { + std::set<std::string>::const_iterator it = filenames.begin(); + for(; it!=filenames.end(); ++it) + { + std::string path; + path = getPath(*it + *ext); + try + { + if (!path.empty() && Poco::File(path).exists()) + { + return path; + } + } + catch(std::exception& e) + { + g_log.error() << "Cannot open file " << path << ": " << e.what() << '\n'; + return ""; + } + } // it + } // ext + return ""; +} + } // namespace DataHandling } // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/OrbiterDataArchive.cpp b/Code/Mantid/Framework/DataHandling/src/OrbiterDataArchive.cpp deleted file mode 100644 index bc14db8ee84b04bce7d88019298cbe9819b40494..0000000000000000000000000000000000000000 --- a/Code/Mantid/Framework/DataHandling/src/OrbiterDataArchive.cpp +++ /dev/null @@ -1,120 +0,0 @@ -//---------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------- -#include "MantidKernel/Logger.h" -#include "MantidDataHandling/OrbiterDataArchive.h" -#include "MantidAPI/ArchiveSearchFactory.h" - -#include <Poco/File.h> -#include <Poco/Net/HTTPSClientSession.h> -#include <Poco/Net/HTTPRequest.h> -#include <Poco/Net/HTTPResponse.h> -#include <Poco/Net/Context.h> -#include <Poco/Net/NetException.h> -#include <Poco/URI.h> -#include <boost/algorithm/string.hpp> - -#include <iostream> - -using Poco::Net::HTTPSClientSession; -using Poco::Net::HTTPRequest; -using Poco::Net::HTTPResponse; -using Poco::Net::HTTPMessage; -using Poco::Net::ConnectionRefusedException; -using Poco::URI; - -namespace Mantid -{ - namespace DataHandling - { - - // Get a reference to the logger - Mantid::Kernel::Logger & OrbiterDataArchive::g_log = Mantid::Kernel::Logger::get("OrbiterDataArchive"); - - DECLARE_ARCHIVESEARCH(OrbiterDataArchive,OrbiterDataSearch); - - /** - * Calls a web service to get a full path to a file - * @param fName :: The file name. - * @return The path to the file or empty string in case of error. - */ - std::string OrbiterDataArchive::getPath(const std::string& fName) const - { - - std::string baseURL( - "https://orbiter.sns.gov/orbiter/current/service/webservice/OrbiterFindFileService.php"); - std::string findFileWS("/operation/findFile/format/space/fileName/"); - std::string URL(baseURL + findFileWS + fName); - g_log.debug() << "URL = \'" << URL << "\'\n"; - - std::string wsResult = ""; - std::string result = ""; - - //#ifdef _WIN32 - // // Return an empty string - //#else - // - //#endif - - Poco::URI uri(URL); - std::string path(uri.getPathAndQuery()); - - Poco::Net::Context::Ptr context = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", - "", Poco::Net::Context::VERIFY_NONE, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); - - try { // workaround for ubuntu 11.04 - Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context); // this line is broken - HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); - session.sendRequest(req); - - HTTPResponse res; - std::istream& rs = session.receiveResponse(res); - - char buff[300]; - std::streamsize n; - - do - { - rs.read(&buff[0], 300); - n = rs.gcount(); - wsResult.append(&buff[0], n); - } while (n == 300); - } catch (ConnectionRefusedException &) { - g_log.information() << "Connection refused by orbiter\n"; - throw; - } catch(Poco::IOException &e) { - g_log.debug() << e.name() << " thrown.\n"; - g_log.information() << e.message() << "\n"; - throw; - } - - //Look for spaces, and split on them. - std::vector<std::string> filenames; - boost::split(filenames, wsResult, boost::is_any_of(" ")); - - // Debug statement to print returned filename(s) - for (std::size_t i = 0; i < filenames.size(); ++i) { - g_log.debug() << "Filename[" << i << "] = \'" << filenames[i] << "\' "; - if (!(filenames[i].empty())) - { - Poco::File temp(filenames[i]); - if (temp.exists()) - { - if (result.empty()) - result = filenames[i]; - g_log.debug() << "exists"; - } - else - { - g_log.debug() << "does not exist"; - } - } - g_log.debug() << "\n"; - } - g_log.debug() << "Returning Filename = \'" << result << "\'\n"; - - return result; - } - - } // namespace DataHandling -} // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp b/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp index 72618579ad2166f7d403c0547f99ce20f79e7e79..af37f214ada269ec2228ac9bf45e514ba433993a 100644 --- a/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp @@ -6,89 +6,109 @@ #include "MantidAPI/ArchiveSearchFactory.h" #include <Poco/File.h> -#include <Poco/Net/HTTPSClientSession.h> +#include <Poco/Net/HTTPClientSession.h> #include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPResponse.h> #include <Poco/Net/Context.h> #include <Poco/Net/NetException.h> #include <Poco/URI.h> #include <boost/algorithm/string.hpp> +#include <Poco/DOM/DOMParser.h> +#include <Poco/DOM/Document.h> +#include <Poco/DOM/Element.h> +#include "Poco/SAX/InputSource.h" +#include <Poco/DOM/NodeList.h> +#include <Poco/DOM/NodeIterator.h> +#include <boost/algorithm/string/predicate.hpp> #include <iostream> -using Poco::Net::HTTPSClientSession; -using Poco::Net::HTTPRequest; -using Poco::Net::HTTPResponse; -using Poco::Net::HTTPMessage; using Poco::Net::ConnectionRefusedException; using Poco::URI; namespace Mantid { - namespace DataHandling +namespace DataHandling +{ + +// Get a reference to the logger +Mantid::Kernel::Logger & SNSDataArchive::g_log = Mantid::Kernel::Logger::get("SNSDataArchive"); + +DECLARE_ARCHIVESEARCH(SNSDataArchive,SNSDataSearch); + +std::string SNSDataArchive::getArchivePath(const std::set<std::string>& filenames, const std::vector<std::string>& exts) const +{ + std::set<std::string>::const_iterator iter = filenames.begin(); + std::string filename = *iter; + + //ICAT4 web service take upper case filename such as HYSA_2662 + std::transform(filename.begin(),filename.end(),filename.begin(),toupper); + + std::vector<std::string>::const_iterator iter2 = exts.begin(); + for(; iter2!=exts.end(); ++iter2) { + g_log.debug() << *iter2 << ";"; + } + g_log.debug() << "\n"; + + std::string baseURL("http://icat.sns.gov:8080/icat-rest-ws/datafile/filename/"); + + std::string URL(baseURL + filename); + g_log.debug() << "URL: " << URL << "\n"; - // Get a reference to the logger - Mantid::Kernel::Logger & SNSDataArchive::g_log = Mantid::Kernel::Logger::get("SNSDataArchive"); + Poco::URI uri(URL); + std::string path(uri.getPathAndQuery()); - DECLARE_ARCHIVESEARCH(SNSDataArchive,SNSDataSearch); + Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort()); + Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1); + session.sendRequest(req); - /** - * Calls a web service to get a full path to a file - * @param fName :: The file name. - * @return The path to the file or empty string in case of error. - */ - std::string SNSDataArchive::getPath(const std::string& fName) const + Poco::Net::HTTPResponse res; + std::istream& rs = session.receiveResponse(res); + g_log.debug() << "res.getStatus(): " << res.getStatus() << "\n"; + + // Create a DOM document from the response. + Poco::XML::DOMParser parser; + Poco::XML::InputSource source(rs); + Poco::XML::Document* pDoc = parser.parse(&source); + + std::vector<std::string> locations; + + // If everything went fine, return the XML document. + // Otherwise look for an error message in the XML document. + if (res.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) + { + std::string location; + Poco::XML::NodeList* pList = pDoc->getElementsByTagName("location"); + for(unsigned long i = 0 ; i < pList->length(); i++) { - std::string baseURL( - "https://prod.sns.gov/sns-icat-ws/icat-location/fileName/"); - std::string URL(baseURL + fName); - g_log.debug() << "SNSDataArchive URL = \'" << URL << "\'\n"; - - std::string wsResult = ""; - - //#ifdef _WIN32 - // // Return an empty string - //#else - // - //#endif - - Poco::URI uri(URL); - std::string path(uri.getPathAndQuery()); - - Poco::Net::Context::Ptr context = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", - "", Poco::Net::Context::VERIFY_NONE, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); - - try { // workaround for ubuntu 11.04 - Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context); // this line is broken - HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); - session.sendRequest(req); - - HTTPResponse res; - std::istream& rs = session.receiveResponse(res); - - char buff[300]; - std::streamsize n; - - do - { - rs.read(&buff[0], 300); - n = rs.gcount(); - wsResult.append(&buff[0], n); - } while (n == 300); - } catch (ConnectionRefusedException &) { - g_log.information() << "Connection refused by prod.sns.gov\n"; - throw; - } catch(Poco::IOException &e) { - g_log.debug() << e.name() << " thrown.\n"; - g_log.information() << e.message() << "\n"; - throw; - } - - g_log.debug() << "SNSDataArchive Returning Filename = \'" << wsResult << "\'\n"; - - return wsResult; + location = pList->item(i)->innerText(); + g_log.debug() << "location: " << location << "\n"; + locations.push_back(location); } + } + else + { + std::string error(res.getReason()); + throw Poco::ApplicationException("HTTPRequest Error", error); + } + + std::vector<std::string>::const_iterator ext = exts.begin(); + for (; ext != exts.end(); ++ext) + { + std::string datafile = filename + *ext; + std::vector<std::string>::const_iterator iter = locations.begin(); + for(; iter!=locations.end(); ++iter) + { + if (boost::algorithm::ends_with((*iter), datafile)) + { + return *iter; + } // end if + } // end for iter + + } // end for ext + return ""; +} - } // namespace DataHandling +} // namespace DataHandling } // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/SNSDataArchiveICAT2.cpp b/Code/Mantid/Framework/DataHandling/src/SNSDataArchiveICAT2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..40dcc52fbad0e0f4296ed75875a210768b14fd99 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/src/SNSDataArchiveICAT2.cpp @@ -0,0 +1,126 @@ +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidKernel/Logger.h" +#include "MantidDataHandling/SNSDataArchiveICAT2.h" +#include "MantidAPI/ArchiveSearchFactory.h" + +#include <Poco/File.h> +#include <Poco/Net/HTTPSClientSession.h> +#include <Poco/Net/HTTPRequest.h> +#include <Poco/Net/HTTPResponse.h> +#include <Poco/Net/Context.h> +#include <Poco/Net/NetException.h> +#include <Poco/URI.h> +#include <boost/algorithm/string.hpp> +#include <Poco/DOM/DOMParser.h> +#include <Poco/DOM/Document.h> +#include <Poco/DOM/Element.h> +#include "Poco/SAX/InputSource.h" +#include <Poco/DOM/NodeList.h> +#include <Poco/DOM/NodeIterator.h> + +#include <iostream> + +using Poco::Net::HTTPSClientSession; +using Poco::Net::HTTPRequest; +using Poco::Net::HTTPResponse; +using Poco::Net::HTTPMessage; +using Poco::Net::ConnectionRefusedException; +using Poco::URI; + +namespace Mantid +{ +namespace DataHandling +{ + +// Get a reference to the logger +Mantid::Kernel::Logger & SNSDataArchiveICAT2::g_log = Mantid::Kernel::Logger::get("SNSDataArchiveICAT2"); + +DECLARE_ARCHIVESEARCH(SNSDataArchiveICAT2,SNSDataSearchICAT2); + +/** + * Calls a web service to get a full path to a file + * @param fName :: The file name. + * @return The path to the file or empty string in case of error. + */ +std::string SNSDataArchiveICAT2::getPath(const std::string& fName) const +{ + std::string baseURL( + "https://prod.sns.gov/sns-icat-ws/icat-location/fileName/"); + std::string URL(baseURL + fName); + g_log.debug() << "SNSDataArchiveICAT2 URL = \'" << URL << "\'\n"; + + std::string wsResult = ""; + + //#ifdef _WIN32 + // // Return an empty string + //#else + // + //#endif + + Poco::URI uri(URL); + std::string path(uri.getPathAndQuery()); + + Poco::Net::Context::Ptr context = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", + "", Poco::Net::Context::VERIFY_NONE, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + + try { // workaround for ubuntu 11.04 + Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context); // this line is broken + HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); + session.sendRequest(req); + + HTTPResponse res; + std::istream& rs = session.receiveResponse(res); + + char buff[300]; + std::streamsize n; + + do + { + rs.read(&buff[0], 300); + n = rs.gcount(); + wsResult.append(&buff[0], n); + } while (n == 300); + } catch (ConnectionRefusedException &) { + g_log.information() << "Connection refused by prod.sns.gov\n"; + throw; + } catch(Poco::IOException &e) { + g_log.debug() << e.name() << " thrown.\n"; + g_log.information() << e.message() << "\n"; + throw; + } + + g_log.debug() << "SNSDataArchiveICAT2 Returning Filename = \'" << wsResult << "\'\n"; + + return wsResult; +} + +std::string SNSDataArchiveICAT2::getArchivePath(const std::set<std::string>& filenames, const std::vector<std::string>& exts) const +{ + std::vector<std::string>::const_iterator ext = exts.begin(); + for (; ext != exts.end(); ++ext) + { + std::set<std::string>::const_iterator it = filenames.begin(); + for(; it!=filenames.end(); ++it) + { + std::string path = getPath(*it + *ext); + try + { + if (!path.empty() && Poco::File(path).exists()) + { + return path; + } + } + catch(std::exception& e) + { + g_log.error() << "Cannot open file " << path << ": " << e.what() << '\n'; + return ""; + } + } // it + } // ext + return ""; +} // end of getArchivePath + +} // namespace DataHandling +} // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/test/ISISDataArchiveTest.h b/Code/Mantid/Framework/DataHandling/test/ISISDataArchiveTest.h index e0e58d35d85245d8db586a1fc661341f04aece86..5b60811f7b5b41227742f1edaa340331d8f2559c 100644 --- a/Code/Mantid/Framework/DataHandling/test/ISISDataArchiveTest.h +++ b/Code/Mantid/Framework/DataHandling/test/ISISDataArchiveTest.h @@ -17,10 +17,17 @@ public: void xtestSearch() { ISISDataArchive arch; - std::string path = arch.getPath("hrpd273"); - std::cout << "(hrp273)= " << path << std::endl; + + std::set<std::string> filename; + filename.insert("hrpd273"); + std::vector<std::string> extension = std::vector<std::string>(1,""); + std::string path = arch.getArchivePath(filename, extension); + std::cout << "(hrpd273)= " << path << std::endl; TS_ASSERT_EQUALS(path.substr(path.size()-18,10),"cycle_98_0"); - path = arch.getPath("hrpds70"); + + filename.clear(); + filename.insert("hrpds70"); + path = arch.getArchivePath(filename, extension); TS_ASSERT(path.empty()); } diff --git a/Code/Mantid/Framework/DataHandling/test/OrbiterDataArchiveTest.h b/Code/Mantid/Framework/DataHandling/test/OrbiterDataArchiveTest.h deleted file mode 100755 index a2b05f99145566f10b467950278511e9a836ceb0..0000000000000000000000000000000000000000 --- a/Code/Mantid/Framework/DataHandling/test/OrbiterDataArchiveTest.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef ORBITERDATAARCHIVETEST_H_ -#define ORBITERDATAARCHIVETEST_H_ - -#include <cxxtest/TestSuite.h> - -#include "MantidDataHandling/OrbiterDataArchive.h" -#include "MantidAPI/ArchiveSearchFactory.h" - -using namespace Mantid::DataHandling; -using namespace Mantid::API; - -class OrbiterDataArchiveTest : public CxxTest::TestSuite -{ -public: - - void xtestSearch() - { - OrbiterDataArchive arch; - std::string path = arch.getPath("cncs_23412_event.nxs"); - //std::cout << "(cncs23412)= " << path << std::endl; - TS_ASSERT_EQUALS(path, "/SNS/CNCS/IPTS-4545/0/23412/NeXus/CNCS_23412_event.nxs"); - - // PG3 Test case - TS_ASSERT_EQUALS(arch.getPath("PG3_2795_event.nxs"), "/SNS/PG3/IPTS-1582/0/2795/NeXus/PG3_2795_event.nxs"); - - // Test a non-existent file - path = arch.getPath("mybeamline_666.nxs"); - TS_ASSERT(path.empty()); - } - - void testFactory() - { - boost::shared_ptr<IArchiveSearch> arch = ArchiveSearchFactory::Instance().create("OrbiterDataSearch"); - TS_ASSERT(arch); - } - -}; - -#endif /*ORBITERDATAARCHIVETEST_H_*/ diff --git a/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveICAT2Test.h b/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveICAT2Test.h new file mode 100644 index 0000000000000000000000000000000000000000..429cec0d84f6ebd4970dd5aba8e89e291162347e --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveICAT2Test.h @@ -0,0 +1,50 @@ +#ifndef SNSDATAARCHIVEICAT2TEST_H_ +#define SNSDATAARCHIVEICAT2TEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidDataHandling/SNSDataArchiveICAT2.h" +#include "MantidAPI/ArchiveSearchFactory.h" + +using namespace Mantid::DataHandling; +using namespace Mantid::API; + +class SNSDataArchiveICAT2Test : public CxxTest::TestSuite +{ +public: + + void xtestSearch() + { + SNSDataArchiveICAT2 arch; + + // PG3 Test case + std::set<std::string> filename; + filename.insert("PG3_7390"); + std::vector<std::string> extension = std::vector<std::string>(1,"_event.nxs"); + std::string path = arch.getArchivePath(filename, extension); + TS_ASSERT_EQUALS(path, "/SNS/PG3/IPTS-2767/0/7390/NeXus/PG3_7390_histo.nxs"); + + + // BSS Test case + filename.clear(); + filename.insert("BSS_18339"); + path = arch.getArchivePath(filename, extension); + TS_ASSERT_EQUALS(path, "/SNS/BSS/IPTS-6817/0/18339/NeXus/BSS_18339_event.nxs"); + + // Test a non-existent file + filename.clear(); + filename.insert("mybeamline_666"); + extension = std::vector<std::string>(1, ".nxs"); + path = arch.getArchivePath(filename, extension); + TS_ASSERT(path.empty()); + } + + void testFactory() + { + boost::shared_ptr<IArchiveSearch> arch = ArchiveSearchFactory::Instance().create("SNSDataSearchICAT2"); + TS_ASSERT(arch); + } + +}; + +#endif /*SNSDATAARCHIVEICAT2TEST_H_*/ diff --git a/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveTest.h b/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveTest.h index a2a278d710764c49861e04ba48fb989689c82573..86d38b13b08ea1d4b125c2e927e0b151bbdbfa8a 100644 --- a/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveTest.h +++ b/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveTest.h @@ -16,14 +16,32 @@ public: void xtestSearch() { SNSDataArchive arch; - std::string path = arch.getPath("PG3_7390_event.nxs"); - TS_ASSERT_EQUALS(path, "/SNS/PG3/IPTS-2767/0/7390/NeXus/PG3_7390_histo.nxs"); // PG3 Test case - TS_ASSERT_EQUALS(arch.getPath("BSS_18339_event.nxs"), "/SNS/BSS/IPTS-6817/0/18339/NeXus/BSS_18339_event.nxs"); + std::set<std::string> filename; + filename.insert("PG3_7390"); + std::vector<std::string> extension = std::vector<std::string>(1,"_event.nxs"); + std::string path = arch.getArchivePath(filename, extension); + TS_ASSERT_EQUALS(path, "/SNS/PG3/IPTS-2767/0/7390/NeXus/PG3_7390_histo.nxs"); + + // BSS Test case + filename.clear(); + filename.insert("BSS_18339"); + path = arch.getArchivePath(filename, extension); + TS_ASSERT_EQUALS(path, "/SNS/BSS/IPTS-6817/0/18339/NeXus/BSS_18339_event.nxs"); + + // HYSA Test case + filename.clear(); + filename.insert("HYSA_2411"); + extension = std::vector<std::string>(1,".nxs.h5"); + path = arch.getArchivePath(filename, extension); + TS_ASSERT_EQUALS(path, "/SNS/HYSA/IPTS-8004/nexus/HYSA_2411.nxs.h5"); // Test a non-existent file - path = arch.getPath("mybeamline_666.nxs"); + filename.clear(); + filename.insert("mybeamline_666"); + extension = std::vector<std::string>(1,".nxs"); + path = arch.getArchivePath(filename, extension); TS_ASSERT(path.empty()); } diff --git a/Code/Mantid/instrument/Facilities.xml b/Code/Mantid/instrument/Facilities.xml index e7b5cda480c5dc1e393f4f82f969fce1fa9e80df..6f96e078998f5a07c3ce861aed538401067fa3b4 100644 --- a/Code/Mantid/instrument/Facilities.xml +++ b/Code/Mantid/instrument/Facilities.xml @@ -265,7 +265,7 @@ <archive> <archiveSearch plugin="SNSDataSearch" /> - <archiveSearch plugin="OrbiterDataSearch" /> + <archiveSearch plugin="SNSDataSearchICAT2" /> </archive> <catalog name="ICat3Catalog">