From 8e0627893ef9c8bd5fd7fcd1ab56af6cc4fe524f Mon Sep 17 00:00:00 2001 From: Martyn Gigg <martyn.gigg@stfc.ac.uk> Date: Mon, 16 Feb 2009 12:31:39 +0000 Subject: [PATCH] Altered ConfigService so that relative path names are converted to absolute ones. Note that the original value is not actually altered but the call for a key is intercepted and a locally stored value is returned. Re #404 --- .../Kernel/inc/MantidKernel/ConfigService.h | 11 +++ Code/Mantid/Kernel/src/ConfigService.cpp | 67 ++++++++++++++++--- Code/Mantid/Kernel/test/ConfigServiceTest.h | 8 ++- 3 files changed, 76 insertions(+), 10 deletions(-) diff --git a/Code/Mantid/Kernel/inc/MantidKernel/ConfigService.h b/Code/Mantid/Kernel/inc/MantidKernel/ConfigService.h index a3a72f63b00..1ca9cd82683 100644 --- a/Code/Mantid/Kernel/inc/MantidKernel/ConfigService.h +++ b/Code/Mantid/Kernel/inc/MantidKernel/ConfigService.h @@ -7,6 +7,8 @@ #include <iostream> #include <iomanip> #include <string> +#include <vector> +#include <map> #include "MantidKernel/DllExport.h" #include "MantidKernel/SingletonHolder.h" @@ -148,9 +150,18 @@ class Logger; /// the POCO system Config Object WrappedObject<Poco::Util::SystemConfiguration>* m_pSysConfig; + /// Convert any relative paths to absolute ones and store them locally so that + /// if the working directory is altered the paths will not be affected + void convertRelativePaths(); + /// static reference to the logger class Logger& g_log; + /// A list of keys that may contain relative paths and need to be altered + std::vector<std::string> m_vConfigPaths; + + /// Local storage for the relative path key/values that have been changed + std::map<std::string, std::string> m_mAbsolutePaths; }; ///Forward declaration of a specialisation of SingletonHolder for AlgorithmFactoryImpl (needed for dllexport/dllimport) and a typedef for it. diff --git a/Code/Mantid/Kernel/src/ConfigService.cpp b/Code/Mantid/Kernel/src/ConfigService.cpp index af86ac678c7..bf4f03b148b 100644 --- a/Code/Mantid/Kernel/src/ConfigService.cpp +++ b/Code/Mantid/Kernel/src/ConfigService.cpp @@ -10,6 +10,7 @@ #include "Poco/Util/SystemConfiguration.h" #include "Poco/Util/PropertyFileConfiguration.h" #include "Poco/LoggingFactory.h" +#include "Poco/Path.h" #include <sstream> #include <iostream> #include <string> @@ -19,12 +20,16 @@ namespace Mantid namespace Kernel { +//------------------------------- +// Private member functions +//------------------------------- + /// Private constructor for singleton class ConfigServiceImpl::ConfigServiceImpl() : g_log(Logger::get("ConfigService")) { - //getting at system details - m_pSysConfig = new WrappedObject<Poco::Util::SystemConfiguration>; - m_pConf = 0; + //getting at system details + m_pSysConfig = new WrappedObject<Poco::Util::SystemConfiguration>; + m_pConf = 0; //Register the FilterChannel with the Poco logging factory Poco::LoggingFactory::defaultFactory().registerChannelClass("FilterChannel",new Poco::Instantiator<Poco::FilterChannel, Poco::Channel>); @@ -32,9 +37,18 @@ namespace Kernel //Register the SignalChannel with the Poco logging factory Poco::LoggingFactory::defaultFactory().registerChannelClass("SignalChannel",new Poco::Instantiator<Poco::SignalChannel, Poco::Channel>); - //attempt to load the default properties filename - loadConfig("Mantid.properties"); - g_log.debug() << "ConfigService created." << std::endl; + //attempt to load the default properties file that resides in the directory of the executable + loadConfig(Mantid::Kernel::getDirectoryOfExecutable() + "Mantid.properties"); + + //Fill the list of possible relative path keys that may require conversion to absolute paths + m_vConfigPaths.clear(); + m_vConfigPaths.push_back("plugins.directory"); + m_vConfigPaths.push_back("instrumentDefinition.directory"); + m_vConfigPaths.push_back("ManagedWorkspace.FilePath"); + + convertRelativePaths(); + + g_log.debug() << "ConfigService created." << std::endl; } /// Private copy constructor for singleton class @@ -52,6 +66,34 @@ namespace Kernel // g_log.debug() << "ConfigService destroyed." << std::endl; } + /** + * Searches the stored list for keys that have been loaded from the config file and may contain + * relative paths. Any it find are converted to absolute paths and stored separately + */ + void ConfigServiceImpl::convertRelativePaths() + { + if( m_vConfigPaths.empty() ) return; + + std::string execdir(Mantid::Kernel::getDirectoryOfExecutable()); + + std::vector<std::string>::const_iterator send = m_vConfigPaths.end(); + for( std::vector<std::string>::const_iterator sitr = m_vConfigPaths.begin(); sitr != send; ++sitr ) + { + if( !m_pConf->hasProperty(*sitr) ) continue; + + std::string value(m_pConf->getString(*sitr)); + if( Poco::Path(value).isRelative() ) + { + m_mAbsolutePaths.insert(std::make_pair(*sitr, Poco::Path(execdir).resolve(value).toString())); + } + + } + + } + +//------------------------------- +// Public member functions +//------------------------------- /** Loads the config file provided, any previous configuration is discarded. * If the file contains logging setup instructions then these will be used to setup the logging framework. @@ -106,15 +148,22 @@ namespace Kernel std::cerr << "Trouble configuring the logging framework " << e.what()<<std::endl; } } + /** Searches for a string within the currently loaded configuaration values and - * returns the value as a string. + * returns the value as a string. If the key is one of those that was a possible relative path + * then the local store is searched first. * * @param keyName The case sensitive name of the property that you need the value of. * @returns The string value of the property, or an empty string if the key cannot be found */ - std::string ConfigServiceImpl::getString(const std::string& keyName) - { + std::string ConfigServiceImpl::getString(const std::string& keyName) + { + std::map<std::string, std::string>::const_iterator mitr = m_mAbsolutePaths.find(keyName); + if( mitr != m_mAbsolutePaths.end() ) + { + return (*mitr).second; + } std::string retVal; try { diff --git a/Code/Mantid/Kernel/test/ConfigServiceTest.h b/Code/Mantid/Kernel/test/ConfigServiceTest.h index 07451886e57..57fdf012685 100644 --- a/Code/Mantid/Kernel/test/ConfigServiceTest.h +++ b/Code/Mantid/Kernel/test/ConfigServiceTest.h @@ -5,6 +5,7 @@ #include "MantidKernel/ConfigService.h" #include "MantidKernel/Logger.h" +#include "Poco/Path.h" #include <string> using namespace Mantid::Kernel; @@ -90,7 +91,12 @@ public: TS_ASSERT_EQUALS(noseCountString, ""); } - + + void TestRelativeToAbsolute() + { + std::string instrumentPath = ConfigService::Instance().getString("instrumentDefinition.directory"); + TS_ASSERT( Poco::Path(instrumentPath).isAbsolute() ); + } private: ConfigService *configSvc; -- GitLab