From 40ae2a12cd7b1dab75702d77af862c70d90a33ee Mon Sep 17 00:00:00 2001
From: Nick Draper <nick.draper@stfc.ac.uk>
Date: Thu, 8 Nov 2007 10:44:32 +0000
Subject: [PATCH] re #60 Exception classes added, existing exception calls have
 not been altered yet.

---
 Code/Mantid/Kernel/Kernel.vcproj     |  18 +--
 Code/Mantid/Kernel/inc/Exception.h   | 204 +++++++++++++++++++++++++++
 Code/Mantid/Kernel/src/Exception.cpp | 188 ++++++++++++++++++++++++
 Code/Mantid/Kernel/src/Logger.cpp    |   4 +-
 4 files changed, 404 insertions(+), 10 deletions(-)
 create mode 100644 Code/Mantid/Kernel/inc/Exception.h
 create mode 100644 Code/Mantid/Kernel/src/Exception.cpp

diff --git a/Code/Mantid/Kernel/Kernel.vcproj b/Code/Mantid/Kernel/Kernel.vcproj
index 0e61a6111be..fb4cb66be5b 100644
--- a/Code/Mantid/Kernel/Kernel.vcproj
+++ b/Code/Mantid/Kernel/Kernel.vcproj
@@ -39,7 +39,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="&quot;C:\Documents and Settings\wmx35332\VisualStudioWorkspace\Mantid\Kernel\inc&quot;;../../Third_Party/include"
+				AdditionalIncludeDirectories="inc;../../Third_Party/include"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
 				RuntimeLibrary="1"
 				DebugInformationFormat="3"
@@ -157,10 +157,6 @@
 				RelativePath=".\src\Algorithm.cpp"
 				>
 			</File>
-			<File
-				RelativePath=".\src\AlgorithmFactory.cpp"
-				>
-			</File>
 			<File
 				RelativePath=".\src\AlgorithmManager.cpp"
 				>
@@ -177,6 +173,10 @@
 				RelativePath=".\src\DllOpen.cpp"
 				>
 			</File>
+			<File
+				RelativePath=".\src\Exception.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\src\FrameworkManager.cpp"
 				>
@@ -211,10 +211,6 @@
 				RelativePath=".\inc\Algorithm.h"
 				>
 			</File>
-			<File
-				RelativePath=".\inc\AlgorithmFactory.h"
-				>
-			</File>
 			<File
 				RelativePath=".\inc\AlgorithmManager.h"
 				>
@@ -239,6 +235,10 @@
 				RelativePath=".\inc\DynamicFactory.h"
 				>
 			</File>
+			<File
+				RelativePath=".\inc\Exception.h"
+				>
+			</File>
 			<File
 				RelativePath=".\inc\FrameworkManager.h"
 				>
diff --git a/Code/Mantid/Kernel/inc/Exception.h b/Code/Mantid/Kernel/inc/Exception.h
new file mode 100644
index 00000000000..06d2d1723c4
--- /dev/null
+++ b/Code/Mantid/Kernel/inc/Exception.h
@@ -0,0 +1,204 @@
+#ifndef MANTID_KERNEL_EXCEPTION_H_
+#define MANTID_KERNEL_EXCEPTION_H_
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <stdexcept>
+#include <System.h>
+
+namespace Mantid
+{
+namespace Kernel
+{
+/** @class Exception Exception.h Kernel/Exception.h
+
+    The Exception classes provide an exception strucure to be used throughout Mantid.
+	All exceptions inherit from std:exception.
+    
+    @author Nick Draper, Tessella Support Services plc
+    @date 8/11/2007
+    
+    Copyright &copy; 2007-8 STFC Rutherford Appleton Laboratories
+
+    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://svn.mantidproject.org/mantid/trunk/Code/Mantid>    
+	Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+class DLLExport Exception: public std::exception
+{
+public:
+	/// Creates an exception.
+	Exception(const std::string& msg);
+	/// Creates an exception.
+	Exception(const std::string& msg, const std::string& arg);
+	/// Creates an exception and stores a clone of the nested exception.
+	Exception(const std::string& msg, const Exception& nested);
+
+	/// Copy constructor.
+	Exception(const Exception& exc);
+
+	/// Destroys the exception and deletes the nested exception.	
+	~Exception() throw();
+	/// Assignment operator.
+	Exception& operator = (const Exception& exc);
+	/// Returns a static string describing the exception.	
+	virtual const char* name() const throw();
+	/// Returns the name of the exception class.	
+	virtual const char* className() const throw();
+	/// Returns a static string describing the exception.
+	///
+	/// Same as name(), but for compatibility with std::exception.
+	virtual const char* what() const throw();
+	/// Returns a pointer to the nested exception, or
+	/// null if no nested exception exists.
+	const Exception* nested() const;
+
+	/// Returns the message text.			
+	const std::string& message() const;
+
+	/// Returns a string consisting of the
+	/// message name and the message text.		
+	std::string displayText() const;
+
+	/// Clones the exception
+	virtual Exception* clone() const;
+
+	/// (Re)Throws the exception.
+	virtual void rethrow() const;
+
+protected:
+	/// Standard constructor.
+	Exception();
+
+		
+private:
+	std::string _msg;
+	Exception*  _pNested;
+};
+
+
+//
+// Macros for quickly declaring and implementing exception classes.
+// Unfortunately, we cannot use a template here because character
+// pointers (which we need for specifying the exception name)
+// are not allowed as template arguments.
+//
+#define MANTID_DECLARE_EXCEPTION(API, CLS, BASE) \
+	class API CLS: public BASE											\
+	{																	\
+	public:																\
+		CLS();															\
+		CLS(const std::string& msg);									\
+		CLS(const std::string& msg, const std::string& arg);			\
+		CLS(const std::string& msg, const Mantid::Kernel::Exception& exc);		\
+		CLS(const CLS& exc);											\
+		~CLS() throw();													\
+		CLS& operator = (const CLS& exc);								\
+		const char* name() const throw();								\
+		const char* className() const throw();							\
+		Mantid::Kernel::Exception* clone() const;									\
+		void rethrow() const;											\
+	};
+
+
+#define MANTID_IMPLEMENT_EXCEPTION(CLS, BASE, NAME) \
+	CLS::CLS()																			\
+	{																					\
+	}																					\
+	CLS::CLS(const std::string& msg): BASE(msg)											\
+	{																					\
+	}																					\
+	CLS::CLS(const std::string& msg, const std::string& arg): BASE(msg, arg)			\
+	{																					\
+	}																					\
+	CLS::CLS(const std::string& msg, const Mantid::Kernel::Exception& exc): BASE(msg, exc)		\
+	{																					\
+	}																					\
+	CLS::CLS(const CLS& exc): BASE(exc)													\
+	{																					\
+	}																					\
+	CLS::~CLS() throw()																	\
+	{																					\
+	}																					\
+	CLS& CLS::operator = (const CLS& exc)												\
+	{																					\
+		BASE::operator = (exc);															\
+		return *this;																	\
+	}																					\
+	const char* CLS::name() const throw()												\
+	{																					\
+		return NAME;																	\
+	}																					\
+	const char* CLS::className() const throw()											\
+	{																					\
+		return typeid(*this).name();													\
+	}																					\
+	Mantid::Kernel::Exception* CLS::clone() const													\
+	{																					\
+		return new CLS(*this);															\
+	}																					\
+	void CLS::rethrow() const															\
+	{																					\
+		throw *this;																	\
+	}
+
+
+//
+// Standard exception classes
+//
+MANTID_DECLARE_EXCEPTION(DLLExport, LogicException, Exception)
+MANTID_DECLARE_EXCEPTION(DLLExport, AssertionViolationException, LogicException)
+MANTID_DECLARE_EXCEPTION(DLLExport, NullPointerException, LogicException)
+MANTID_DECLARE_EXCEPTION(DLLExport, InvalidArgumentException, LogicException)
+MANTID_DECLARE_EXCEPTION(DLLExport, NotImplementedException, LogicException)
+MANTID_DECLARE_EXCEPTION(DLLExport, RangeException, LogicException)
+
+MANTID_DECLARE_EXCEPTION(DLLExport, RuntimeException, Exception)
+MANTID_DECLARE_EXCEPTION(DLLExport, NotFoundException, RuntimeException)
+MANTID_DECLARE_EXCEPTION(DLLExport, ExistsException, RuntimeException)
+MANTID_DECLARE_EXCEPTION(DLLExport, TimeoutException, RuntimeException)
+MANTID_DECLARE_EXCEPTION(DLLExport, SystemException, RuntimeException)
+MANTID_DECLARE_EXCEPTION(DLLExport, LibraryLoadException, RuntimeException)
+MANTID_DECLARE_EXCEPTION(DLLExport, LibraryAlreadyLoadedException, RuntimeException)
+MANTID_DECLARE_EXCEPTION(DLLExport, NoPermissionException, RuntimeException)
+MANTID_DECLARE_EXCEPTION(DLLExport, OutOfMemoryException, RuntimeException)
+MANTID_DECLARE_EXCEPTION(DLLExport, DataException, RuntimeException)
+
+MANTID_DECLARE_EXCEPTION(DLLExport, DataFormatException, DataException)
+MANTID_DECLARE_EXCEPTION(DLLExport, SyntaxException, DataException)
+MANTID_DECLARE_EXCEPTION(DLLExport, PathSyntaxException, SyntaxException)
+MANTID_DECLARE_EXCEPTION(DLLExport, IOException, RuntimeException)
+MANTID_DECLARE_EXCEPTION(DLLExport, FileException, IOException)
+MANTID_DECLARE_EXCEPTION(DLLExport, FileExistsException, FileException)
+MANTID_DECLARE_EXCEPTION(DLLExport, FileNotFoundException, FileException)
+MANTID_DECLARE_EXCEPTION(DLLExport, PathNotFoundException, FileException)
+MANTID_DECLARE_EXCEPTION(DLLExport, FileReadOnlyException, FileException)
+MANTID_DECLARE_EXCEPTION(DLLExport, FileAccessDeniedException, FileException)
+MANTID_DECLARE_EXCEPTION(DLLExport, CreateFileException, FileException)
+MANTID_DECLARE_EXCEPTION(DLLExport, OpenFileException, FileException)
+MANTID_DECLARE_EXCEPTION(DLLExport, WriteFileException, FileException)
+MANTID_DECLARE_EXCEPTION(DLLExport, ReadFileException, FileException)
+
+MANTID_DECLARE_EXCEPTION(DLLExport, ApplicationException, Exception)
+MANTID_DECLARE_EXCEPTION(DLLExport, BadCastException, RuntimeException)
+
+
+} // namespace Kernel
+} // namespace Mantid
+
+#endif // MANTID_KERNEL_EXCEPTION_H_
diff --git a/Code/Mantid/Kernel/src/Exception.cpp b/Code/Mantid/Kernel/src/Exception.cpp
new file mode 100644
index 00000000000..4fff76b0c06
--- /dev/null
+++ b/Code/Mantid/Kernel/src/Exception.cpp
@@ -0,0 +1,188 @@
+#include "Exception.h"
+#include <typeinfo>
+
+
+namespace Mantid
+{
+namespace Kernel
+{
+
+/** No Arg Constructor
+	Intialises the nested exception to 0
+*/
+Exception::Exception(): _pNested(0)
+{
+}
+
+/** Constructor
+	@param msg Sets the message that the Exception will carry
+*/
+Exception::Exception(const std::string& msg): _msg(msg), _pNested(0)
+{
+}
+
+/** Constructor
+	@param msg Sets the message that the Exception will carry
+	@param arg message arguments are appeneded to the end of the message with a preceding ': '
+*/
+Exception::Exception(const std::string& msg, const std::string& arg): _msg(msg), _pNested(0)
+{
+	if (!arg.empty())
+	{
+		_msg.append(": ");
+		_msg.append(arg);
+	}
+}
+
+/** Constructor
+	@param msg Sets the message that the Exception will carry
+	@param nested A nested exception which is cloned and held within this exception
+*/
+Exception::Exception(const std::string& msg, const Exception& nested): _msg(msg), _pNested(nested.clone())
+{
+}
+
+/** Constructor
+	@param nested A nested exception, the message for this exception is taken from the inner exception
+*/
+Exception::Exception(const Exception& exc): std::exception(exc)
+{
+	_msg = exc._msg;
+	_pNested = exc._pNested ? exc._pNested->clone() : 0;
+}
+
+/// Destructor
+Exception::~Exception() throw()
+{
+	delete _pNested;
+}
+
+/** Copy contructor
+	@param exc The excption to copy
+	@returns The copied exception
+*/
+Exception& Exception::operator = (const Exception& exc)
+{
+	if (&exc != this)
+	{
+		delete _pNested;
+		_msg = exc._msg;
+		_pNested = exc._pNested ? exc._pNested->clone() : 0;
+	}
+	return *this;
+}
+
+/** Gets the name of the exception
+	@returns the name of the exception
+*/
+const char* Exception::name() const throw()
+{
+	return "Exception";
+}
+
+/** Gets the classname of the exception
+	@returns the classname of the exception
+*/
+const char* Exception::className() const throw()
+{
+	return typeid(*this).name();
+}
+
+/** Gets the name of the exception (compatible with std::exception)
+	@returns the name of the exception
+*/
+const char* Exception::what() const throw()
+{
+	return name();
+}
+
+/** Gets the name and message of the exception formatted for display or logging
+	@returns the name and message of the exception
+*/
+std::string Exception::displayText() const
+{
+	std::string txt = name();
+	if (!_msg.empty())
+	{
+		txt.append(": ");
+		txt.append(_msg);
+	}
+	return txt;
+}
+
+/** Creates an exact copy of the exception.
+	The copy can later be thrown again by
+	invoking rethrow() on it.
+	@returns A pointer to the cloned exception
+*/
+Exception* Exception::clone() const
+{
+	return new Exception(*this);
+}
+
+/** (Re)Throws the exception.
+	This is useful for temporarily storing a
+	copy of an exception (see clone()), then
+	throwing it again.	
+*/
+void Exception::rethrow() const
+{
+	throw *this;
+}
+
+/** Gets the nested exception
+	@returns A pointer to the nested exception
+*/
+const Exception* Exception::nested() const
+{
+	return _pNested;
+}
+
+/** gets the message of the exception
+	@returns A reference to the message
+*/
+const std::string& Exception::message() const
+{
+	return _msg;
+}
+
+
+MANTID_IMPLEMENT_EXCEPTION(LogicException, Exception, "Logic exception")
+MANTID_IMPLEMENT_EXCEPTION(AssertionViolationException, LogicException, "Assertion violation")
+MANTID_IMPLEMENT_EXCEPTION(NullPointerException, LogicException, "Null pointer")
+MANTID_IMPLEMENT_EXCEPTION(InvalidArgumentException, LogicException, "Invalid argument")
+MANTID_IMPLEMENT_EXCEPTION(NotImplementedException, LogicException, "Not implemented")
+MANTID_IMPLEMENT_EXCEPTION(RangeException, LogicException, "Out of range")
+
+MANTID_IMPLEMENT_EXCEPTION(RuntimeException, Exception, "Runtime exception")
+MANTID_IMPLEMENT_EXCEPTION(NotFoundException, RuntimeException, "Not found")
+MANTID_IMPLEMENT_EXCEPTION(ExistsException, RuntimeException, "Exists")
+MANTID_IMPLEMENT_EXCEPTION(TimeoutException, RuntimeException, "Timeout")
+MANTID_IMPLEMENT_EXCEPTION(SystemException, RuntimeException, "System exception")
+MANTID_IMPLEMENT_EXCEPTION(LibraryLoadException, RuntimeException, "Cannot load library")
+MANTID_IMPLEMENT_EXCEPTION(LibraryAlreadyLoadedException, RuntimeException, "Library already loaded")
+MANTID_IMPLEMENT_EXCEPTION(NoPermissionException, RuntimeException, "No permission")
+MANTID_IMPLEMENT_EXCEPTION(OutOfMemoryException, RuntimeException, "Out of memory")
+MANTID_IMPLEMENT_EXCEPTION(DataException, RuntimeException, "Data error")
+
+MANTID_IMPLEMENT_EXCEPTION(DataFormatException, DataException, "Bad data format")
+MANTID_IMPLEMENT_EXCEPTION(SyntaxException, DataException, "Syntax error")
+MANTID_IMPLEMENT_EXCEPTION(PathSyntaxException, SyntaxException, "Bad path syntax")
+MANTID_IMPLEMENT_EXCEPTION(IOException, RuntimeException, "I/O error")
+MANTID_IMPLEMENT_EXCEPTION(FileException, IOException, "File access error")
+MANTID_IMPLEMENT_EXCEPTION(FileExistsException, FileException, "File exists")
+MANTID_IMPLEMENT_EXCEPTION(FileNotFoundException, FileException, "File not found")
+MANTID_IMPLEMENT_EXCEPTION(PathNotFoundException, FileException, "Path not found")
+MANTID_IMPLEMENT_EXCEPTION(FileReadOnlyException, FileException, "File is read-only")
+MANTID_IMPLEMENT_EXCEPTION(FileAccessDeniedException, FileException, "Access to file denied")
+MANTID_IMPLEMENT_EXCEPTION(CreateFileException, FileException, "Cannot create file")
+MANTID_IMPLEMENT_EXCEPTION(OpenFileException, FileException, "Cannot open file")
+MANTID_IMPLEMENT_EXCEPTION(WriteFileException, FileException, "Cannot write file")
+MANTID_IMPLEMENT_EXCEPTION(ReadFileException, FileException, "Cannot read file")
+
+
+MANTID_IMPLEMENT_EXCEPTION(ApplicationException, Exception, "Application exception")
+MANTID_IMPLEMENT_EXCEPTION(BadCastException, RuntimeException, "Bad cast exception")
+
+} // namespace Kernel
+} // namespace Mantid
diff --git a/Code/Mantid/Kernel/src/Logger.cpp b/Code/Mantid/Kernel/src/Logger.cpp
index 8aeb355cabb..023f32f5ae0 100755
--- a/Code/Mantid/Kernel/src/Logger.cpp
+++ b/Code/Mantid/Kernel/src/Logger.cpp
@@ -107,15 +107,17 @@ namespace Kernel
 
 	bool Logger::is(int level) const
 	{
+		bool retVal = false;
 		try
 		{
-			return _log.is(level);
+			retVal = _log.is(level);
 		} 
 		catch (std::exception& e)
 		{
 			//failures in logging are not allowed to throw exceptions out of the logging class
 			std::cerr << e.what();
 		}
+		return retVal;
 	}
 
 	void Logger::shutdown()
-- 
GitLab