From c5ab6b955dfc544c1a43f00d526ebbb7829d1211 Mon Sep 17 00:00:00 2001
From: Martyn Gigg <martyn.gigg@stfc.ac.uk>
Date: Tue, 25 Jun 2013 16:00:58 +0100
Subject: [PATCH] Add basic code for FileLoaderRegistry. Refs #7263

Currently based on string names.
---
 Code/Mantid/Framework/API/CMakeLists.txt      |  3 +
 .../API/inc/MantidAPI/FileLoaderRegistry.h    | 58 +++++++++++++++++++
 .../Framework/API/src/FileLoaderRegistry.cpp  | 53 +++++++++++++++++
 .../API/test/FileLoaderRegistryTest.h         | 53 +++++++++++++++++
 4 files changed, 167 insertions(+)
 create mode 100644 Code/Mantid/Framework/API/inc/MantidAPI/FileLoaderRegistry.h
 create mode 100644 Code/Mantid/Framework/API/src/FileLoaderRegistry.cpp
 create mode 100644 Code/Mantid/Framework/API/test/FileLoaderRegistryTest.h

diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt
index ca8718a017d..59ef155b9bf 100644
--- a/Code/Mantid/Framework/API/CMakeLists.txt
+++ b/Code/Mantid/Framework/API/CMakeLists.txt
@@ -28,6 +28,7 @@ set ( SRC_FILES
 	src/Expression.cpp
 	src/FermiChopperModel.cpp
 	src/FileFinder.cpp
+	src/FileLoaderRegistry.cpp
 	src/FileProperty.cpp
 	src/FrameworkManager.cpp
 	src/FuncMinimizerFactory.cpp
@@ -152,6 +153,7 @@ set ( INC_FILES
 	inc/MantidAPI/Expression.h
 	inc/MantidAPI/FermiChopperModel.h
 	inc/MantidAPI/FileFinder.h
+	inc/MantidAPI/FileLoaderRegistry.h
 	inc/MantidAPI/FileProperty.h
 	inc/MantidAPI/FrameworkManager.h
 	inc/MantidAPI/FuncMinimizerFactory.h
@@ -282,6 +284,7 @@ set ( TEST_FILES
 	ExpressionTest.h
 	FermiChopperModelTest.h
 	FileFinderTest.h
+	FileLoaderRegistryTest.h
 	FilePropertyTest.h
 	FrameworkManagerTest.h
 	FuncMinimizerFactoryTest.h
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FileLoaderRegistry.h b/Code/Mantid/Framework/API/inc/MantidAPI/FileLoaderRegistry.h
new file mode 100644
index 00000000000..b3a06cd6efe
--- /dev/null
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/FileLoaderRegistry.h
@@ -0,0 +1,58 @@
+#ifndef MANTID_API_FILELOADERREGISTRY_H_
+#define MANTID_API_FILELOADERREGISTRY_H_
+
+#include "MantidAPI/DllConfig.h"
+
+#include <set>
+#include <string>
+
+namespace Mantid
+{
+  namespace API
+  {
+
+    /**
+
+
+    Copyright &copy; 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
+
+    This file is part of Mantid.
+
+    Mantid 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.
+
+    Mantid 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/>.
+
+    File change history is stored at: <https://github.com/mantidproject/mantid>
+    Code Documentation is available at: <http://doxygen.mantidproject.org>
+     */
+    class MANTID_API_DLL FileLoaderRegistry
+    {
+    public:
+      /// Default constructor
+      FileLoaderRegistry();
+
+      /// @returns the number of entries in the registry
+      inline size_t size() const { return m_names.size(); }
+      /// Adds an entry
+      void subscribe(const std::string & name);
+      /// Pick the best loader for the given filename
+      std::string findLoader(const std::string & filename) const;
+
+    private:
+      /// The registered names
+      std::set<std::string> m_names;
+    };
+
+  } // namespace API
+} // namespace Mantid
+
+#endif  /* MANTID_API_FILELOADERREGISTRY_H_ */
diff --git a/Code/Mantid/Framework/API/src/FileLoaderRegistry.cpp b/Code/Mantid/Framework/API/src/FileLoaderRegistry.cpp
new file mode 100644
index 00000000000..229c92c608c
--- /dev/null
+++ b/Code/Mantid/Framework/API/src/FileLoaderRegistry.cpp
@@ -0,0 +1,53 @@
+#include "MantidAPI/FileLoaderRegistry.h"
+#include "MantidKernel/Exception.h"
+
+#include <Poco/File.h>
+
+namespace Mantid
+{
+  namespace API
+  {
+    //----------------------------------------------------------------------------------------------
+    // Public members
+    //----------------------------------------------------------------------------------------------
+    /**
+     * Creates an empty registry
+     */
+    FileLoaderRegistry::FileLoaderRegistry()
+    {
+    }
+
+    /**
+     * @param name The string name of the entry
+     * @throws std::invalid_argument if an entry with this name already exists
+     */
+    void FileLoaderRegistry::subscribe(const std::string & name)
+    {
+      auto insertionResult = m_names.insert(name);
+      if(!insertionResult.second)
+      {
+        throw std::invalid_argument("FileLoaderRegistry::subscribe - Cannot subscribe '"
+            + name + "'. An entry with that name already exists");
+      }
+    }
+
+    /**
+     * Attempts to pick the best suited loader for the given file name from those in the registry
+     * @param filename A string that should point to an existing file
+     * @throws std::invalid_argument if the filename does not point to an existing file or an empty string is given
+     * @throws Exception::NotFoundError if a loader could not be found
+     */
+    std::string FileLoaderRegistry::findLoader(const std::string & filename) const
+    {
+      if(filename.empty() || !Poco::File(filename).exists())
+      {
+        throw std::invalid_argument("FileLoaderRegistry::chooserLoader - Cannot open file '" + filename + "'");
+      }
+    }
+
+    //----------------------------------------------------------------------------------------------
+    // Private members
+    //----------------------------------------------------------------------------------------------
+
+  } // namespace API
+} // namespace Mantid
diff --git a/Code/Mantid/Framework/API/test/FileLoaderRegistryTest.h b/Code/Mantid/Framework/API/test/FileLoaderRegistryTest.h
new file mode 100644
index 00000000000..ba85ec20c60
--- /dev/null
+++ b/Code/Mantid/Framework/API/test/FileLoaderRegistryTest.h
@@ -0,0 +1,53 @@
+#ifndef MANTID_API_FILELOADERREGISTRYTEST_H_
+#define MANTID_API_FILELOADERREGISTRYTEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include "MantidAPI/FileLoaderRegistry.h"
+
+using Mantid::API::FileLoaderRegistry;
+
+class FileLoaderRegistryTest : public CxxTest::TestSuite
+{
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static FileLoaderRegistryTest *createSuite() { return new FileLoaderRegistryTest(); }
+  static void destroySuite( FileLoaderRegistryTest *suite ) { delete suite; }
+
+  void test_Construction_Gives_Empty_Registry()
+  {
+    FileLoaderRegistry registry;
+
+    TS_ASSERT_EQUALS(0, registry.size());
+  }
+
+  void test_Subscribing_Entry_That_Does_Not_Exist_Increases_Size_By_One()
+  {
+    FileLoaderRegistry registry;
+
+    TS_ASSERT_THROWS_NOTHING(registry.subscribe("LoadEventNexus"));
+    TS_ASSERT_EQUALS(1, registry.size());
+  }
+
+  // ======================== Failure cases ===================================
+  void test_Adding_Entry_That_Already_Exists_Throws_Error_And_Keeps_The_Size_The_Same()
+  {
+    FileLoaderRegistry registry;
+    registry.subscribe("LoadEventNexus");
+
+    TS_ASSERT_THROWS(registry.subscribe("LoadEventNexus"), std::invalid_argument);
+    TS_ASSERT_EQUALS(1, registry.size());
+  }
+
+  void test_Finding_A_Loader_Throws_Invalid_Argument_If_Filename_Does_Not_Point_To_Valid_File()
+  {
+    FileLoaderRegistry registry;
+
+    TS_ASSERT_THROWS(registry.findLoader(""), std::invalid_argument);
+    TS_ASSERT_THROWS(registry.findLoader("__notafile.txt__"), std::invalid_argument);
+  }
+
+};
+
+
+#endif /* MANTID_API_FILELOADERREGISTRYTEST_H_ */
-- 
GitLab