Newer
Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/Support.h"
#include "MantidKernel/Logger.h"
#include "Poco/Util/LoggingConfigurator.h"
#include "Poco/Util/SystemConfiguration.h"
#include "Poco/Util/PropertyFileConfiguration.h"
Gigg, Martyn Anthony
committed
#include "Poco/Path.h"
Nick Draper
committed
#include <sstream>
#include <iostream>
#include <string>
namespace Mantid
Russell Taylor
committed
{
namespace Kernel
Gigg, Martyn Anthony
committed
//-------------------------------
// Private member functions
//-------------------------------
/// Private constructor for singleton class
ConfigServiceImpl::ConfigServiceImpl() : g_log(Logger::get("ConfigService"))
{
Gigg, Martyn Anthony
committed
//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>);
//Register the SignalChannel with the Poco logging factory
Poco::LoggingFactory::defaultFactory().registerChannelClass("SignalChannel",new Poco::Instantiator<Poco::SignalChannel, Poco::Channel>);
Gigg, Martyn Anthony
committed
//Determine how we are running mantid
if( Mantid::Kernel::getPathToExecutable().rfind("python") != std::string::npos )
{
m_strBaseDir = Poco::Path::current();
}
else
{
m_strBaseDir = Mantid::Kernel::getDirectoryOfExecutable();
}
Gigg, Martyn Anthony
committed
//attempt to load the default properties file that resides in the directory of the executable
Gigg, Martyn Anthony
committed
loadConfig( getBaseDir() + "Mantid.properties");
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
//Fill the list of possible relative path keys that may require conversion to absolute paths
Gigg, Martyn Anthony
committed
m_vConfigPaths.clear();
m_vConfigPaths.push_back("plugins.directory");
m_vConfigPaths.push_back("instrumentDefinition.directory");
Gigg, Martyn Anthony
committed
m_vConfigPaths.push_back("pythonscripts.directory");
Gigg, Martyn Anthony
committed
m_vConfigPaths.push_back("ManagedWorkspace.FilePath");
convertRelativePaths();
g_log.debug() << "ConfigService created." << std::endl;
Gigg, Martyn Anthony
committed
g_log.debug() << "Configured base directory of application as " << getBaseDir() << std::endl;
}
/// Private copy constructor for singleton class
ConfigServiceImpl::ConfigServiceImpl(const ConfigServiceImpl&) : g_log(Logger::get("ConfigService"))
{
}
/** Private Destructor
* Prevents client from calling 'delete' on the pointer handed out by Instance
*/
ConfigServiceImpl::~ConfigServiceImpl()
{
delete m_pSysConfig;
// g_log.debug() << "ConfigService destroyed." << std::endl;
}
Gigg, Martyn Anthony
committed
/**
* 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;
Gigg, Martyn Anthony
committed
std::string execdir(getBaseDir());
Gigg, Martyn Anthony
committed
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.
*
* @param filename The filename and optionally path of the file to load
*/
void ConfigServiceImpl::loadConfig(const std::string& filename)
{
delete m_pConf;
try
{
m_pConf = new WrappedObject<Poco::Util::PropertyFileConfiguration>(filename);
}
{
//there was a problem loading the file - it probably is not there
Russell Taylor
committed
std::cerr << "Problem loading the logging file " << filename << " " << e.what() << std::endl;
Nick Draper
committed
std::string propFile =
"logging.loggers.root.level = debug\n"
"logging.loggers.root.channel.class = SplitterChannel\n"
"logging.loggers.root.channel.channel1 = consoleChannelFilter\n"
Nick Draper
committed
"logging.loggers.root.channel.channel2 = fileChannel\n"
"logging.channels.consoleChannelFilter.class = FilterChannel\n"
"logging.channels.consoleChannelFilter.channel = ConsoleChannel\n"
"logging.channels.consoleChannelFilter.level = information\n"
Nick Draper
committed
"logging.channels.consoleChannel.class = ConsoleChannel\n"
"logging.channels.consoleChannel.formatter = f1\n"
"logging.channels.fileChannel.class = FileChannel\n"
"logging.channels.fileChannel.path = mantid.log\n"
Nick Draper
committed
"logging.channels.fileChannel.formatter.class = PatternFormatter\n"
"logging.channels.fileChannel.formatter.pattern = %Y-%m-%d %H:%M:%S,%i [%I] %p %s - %t\n"
Nick Draper
committed
"logging.formatters.f1.class = PatternFormatter\n"
"logging.formatters.f1.pattern = %s-[%p] %t\n"
"logging.formatters.f1.times = UTC\n";
std::istringstream istr(propFile);
m_pConf = new WrappedObject<Poco::Util::PropertyFileConfiguration>(istr);
}
try
{
//configure the logging framework
Nick Draper
committed
Poco::Util::LoggingConfigurator configurator;
//BUG? This line crashes the FrameworkManagerTest and ConfigServiceImplTest
configurator.configure(m_pConf);
}
{
std::cerr << "Trouble configuring the logging framework " << e.what()<<std::endl;
}
}
Gigg, Martyn Anthony
committed
/** Searches for a string within the currently loaded configuaration values and
Gigg, Martyn Anthony
committed
* 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
Gigg, Martyn Anthony
committed
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
{
retVal = m_pConf->getString(keyName);
}
catch(Poco::NotFoundException& ex)
{
g_log.debug()<<"Unable to find " << keyName << " in the properties file" << std::endl;
}
/** Searches for a string within the currently loaded configuaration values and
* attempts to convert the values to the template type supplied.
*
* @param keyName The case sensitive name of the property that you need the value of.
* @param out The value if found
* @returns A success flag - 0 on failure, 1 on success
*/
template<typename T>
int ConfigServiceImpl::getValue(const std::string& keyName, T& out)
{
std::string strValue = getString(keyName);
Russell Taylor
committed
int result = StrFunc::convert(strValue,out);
return result;
}
/** Searches for the string within the environment variables and returns the
* value as a string.
*
* @param keyName The name of the environment variable that you need the value of.
* @returns The string value of the property
*/
std::string ConfigServiceImpl::getEnvironment(const std::string& keyName)
{
return m_pSysConfig->getString("system.env." + keyName);
}
/** Gets the name of the host operating system
*
* @returns The name pf the OS version
*/
std::string ConfigServiceImpl::getOSName()
{
return m_pSysConfig->getString("system.osName");
}
/** Gets the name of the computer running Mantid
*
* @returns The name of the computer
*/
std::string ConfigServiceImpl::getOSArchitecture()
{
return m_pSysConfig->getString("system.osArchitecture");
}
/** Gets the name of the operating system Architecture
*
* @returns The operating system architecture
*/
std::string ConfigServiceImpl::getComputerName()
{
return m_pSysConfig->getString("system.nodeName");
}
/** Gets the name of the operating system version
*
* @returns The operating system version
*/
std::string ConfigServiceImpl::getOSVersion()
{
return m_pSysConfig->getString("system.osVersion");
}
/** Gets the absolute path of the current directory containing the dll
*
* @returns The absolute path of the current directory containing the dll
*/
std::string ConfigServiceImpl::getCurrentDir()
{
return m_pSysConfig->getString("system.currentDir");
}
/** Gets the absolute path of the temp directory
*
* @returns The absolute path of the temp directory
*/
std::string ConfigServiceImpl::getTempDir()
{
return m_pSysConfig->getString("system.tempDir");
}
Gigg, Martyn Anthony
committed
/**
* Gets the directory that we consider to be the bse directory. Basically, this is the
* executable directory when running normally or the current directory on startup when
* running through Python on the command line
* @returns The directory to consider as the base directory, including a trailing slash
*/
std::string ConfigServiceImpl::getBaseDir()
{
return m_strBaseDir;
}
template DLLExport int ConfigServiceImpl::getValue(const std::string&,double&);
template DLLExport int ConfigServiceImpl::getValue(const std::string&,std::string&);
template DLLExport int ConfigServiceImpl::getValue(const std::string&,int&);
Russell Taylor
committed
} // namespace Kernel
} // namespace Mantid