Skip to content
Snippets Groups Projects
ConfigService.cpp 44.5 KiB
Newer Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/MantidVersion.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/FilterChannel.h"
#include "MantidKernel/SignalChannel.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/FacilityInfo.h"
Campbell, Stuart's avatar
Campbell, Stuart committed
#include <Poco/Util/LoggingConfigurator.h>
#include <Poco/Util/SystemConfiguration.h>
#include <Poco/Util/PropertyFileConfiguration.h>
#include <Poco/LoggingFactory.h>
#include <Poco/Path.h>
#include <Poco/File.h>
#include <Poco/StringTokenizer.h>
#include <Poco/DOM/DOMParser.h>
#include <Poco/DOM/Document.h>
#include <Poco/DOM/Element.h>
#include <Poco/DOM/NodeList.h>
#include <Poco/Notification.h>
#include <Poco/Environment.h>
#include <boost/algorithm/string/replace.hpp>
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <algorithm>
Russell Taylor's avatar
Russell Taylor committed
#ifdef __APPLE__
  #include <mach-o/dyld.h>
#endif

namespace Mantid
{
/**
 * Get the welcome message for Mantid.
 * @returns A string containing the welcome message for Mantid.
 */
std::string welcomeMessage()
{
  return "Welcome to Mantid - Manipulation and Analysis Toolkit for Instrument Data";
}
namespace Kernel
{

/** Inner templated class to wrap the poco library objects that have protected
 *  destructors and expose them as public.
 */
template<typename T>
class ConfigServiceImpl::WrappedObject: public T
{
public:
  /// The template type of class that is being wrapped
  typedef T element_type;
  /// Simple constructor
  WrappedObject() :
    T()
  {
    m_pPtr = static_cast<T*> (this);
  }

  /** Constructor with a class to wrap
  template<typename Field>
  WrappedObject(Field& F) :
    T(F)
  {
    m_pPtr = static_cast<T*> (this);
  }
  /// Copy constructor
  WrappedObject(const WrappedObject<T>& A) :
    T(A)
  {
    m_pPtr = static_cast<T*> (this);
  }
  /// Overloaded * operator returns the wrapped object pointer
  const T& operator*() const
  {
    return *m_pPtr;
  }
  /// Overloaded * operator returns the wrapped object pointer
  T& operator*()
  {
    return m_pPtr;
  }
  /// Overloaded -> operator returns the wrapped object pointer
  const T* operator->() const
  {
    return m_pPtr;
  }
  /// Overloaded -> operator returns the wrapped object pointer
  T* operator->()
  {
    return m_pPtr;
  }
private:
  /// Private pointer to the wrapped class
  T* m_pPtr;
};
//Back to the ConfigService class itself...
//-------------------------------
// Private member functions
//-------------------------------
/// Private constructor for singleton class
ConfigServiceImpl::ConfigServiceImpl() :
  m_pConf(NULL), m_pSysConfig(NULL), g_log(Logger::get("ConfigService")), m_changed_keys(),
      m_ConfigPaths(), m_AbsolutePaths(), m_strBaseDir(""), m_PropertyString(""),
      m_properties_file_name("Mantid.properties"),
      m_user_properties_file_name("Mantid.user.properties"), m_DataSearchDirs(), m_UserSearchDirs(),
      m_instr_prefixes()
{
  //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>);

  // Define the directory to search for the Mantid.properties file.
  Poco::File f;

  // First directory: the current working
  m_strBaseDir = Poco::Path::current();
  f = Poco::File(m_strBaseDir + m_properties_file_name);
Nick Draper's avatar
Nick Draper committed
  if (!f.exists())
    // Check the executable directory to see if it includes a mantid.properties file
    f = Poco::File(m_strBaseDir + m_properties_file_name);
    if (!f.exists())
Nick Draper's avatar
Nick Draper committed
    {
      // Last, use the MANTIDPATH environment var
      if (Poco::Environment::has("MANTIDPATH"))
      {
        // Here we have to follow the convention of the rest of this code and add a trailing slash.
        // Note: adding it to the MANTIDPATH itself will make other parts of the code crash.
        m_strBaseDir = Poco::Environment::get("MANTIDPATH") + "/";
      }
Nick Draper's avatar
Nick Draper committed
    }
  //Fill the list of possible relative path keys that may require conversion to absolute paths
  m_ConfigPaths.insert(std::make_pair("plugins.directory", true));
  m_ConfigPaths.insert(std::make_pair("mantidqt.plugins.directory", true));
  m_ConfigPaths.insert(std::make_pair("instrumentDefinition.directory", true));
  m_ConfigPaths.insert(std::make_pair("parameterDefinition.directory", true));
  m_ConfigPaths.insert(std::make_pair("requiredpythonscript.directories", true));
  m_ConfigPaths.insert(std::make_pair("pythonscripts.directory", true));
  m_ConfigPaths.insert(std::make_pair("pythonscripts.directories", true));
  m_ConfigPaths.insert(std::make_pair("ManagedWorkspace.FilePath", true));
  m_ConfigPaths.insert(std::make_pair("defaultsave.directory", false));
  m_ConfigPaths.insert(std::make_pair("datasearch.directories", true));
  m_ConfigPaths.insert(std::make_pair("pythonalgorithms.directories", true));
  m_ConfigPaths.insert(std::make_pair("icatDownload.directory", true));
  m_ConfigPaths.insert(std::make_pair("mantidqt.python_interfaces_directory", true));

  //attempt to load the default properties file that resides in the directory of the executable
  updateConfig(getPropertiesDir() + m_properties_file_name, false, false);
  propertiesFilesList = getPropertiesDir() + m_properties_file_name;

  // Load the local (machine) properties file, if it exists
  Poco::File localFile(getLocalFilename());
  if ( localFile.exists() )
  {
    updateConfig(getLocalFilename(), true, false);
    propertiesFilesList += ", " + getLocalFilename();
  }
  if (Poco::Environment::has("MANTIDPROPERTIES"))
  {
    //and then append the user properties
    updateConfig(getUserFilename(), true, false);
    propertiesFilesList += ", " + getUserFilename();
Loading
Loading full blame...