Skip to content
Snippets Groups Projects
ConfigService.cpp 66.7 KiB
Newer Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/DateAndTime.h"
#include "MantidKernel/MantidVersion.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/FilterChannel.h"
#include "MantidKernel/StdoutChannel.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/FacilityInfo.h"
#include "MantidKernel/NetworkProxy.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 <MantidKernel/StringTokenizer.h>
Campbell, Stuart's avatar
Campbell, Stuart committed
#include <Poco/DOM/DOMParser.h>
#include <Poco/DOM/Document.h>
#include <Poco/DOM/NodeList.h>
#include <Poco/Environment.h>
#include <Poco/URI.h>
#pragma warning(disable : 4250)
#include <Poco/Logger.h>
#include <Poco/SplitterChannel.h>
#include <Poco/LoggingRegistry.h>
#include <Poco/PipeStream.h>
#include <Poco/StreamCopier.h>
#include <boost/regex.hpp>
#include <fstream>

Russell Taylor's avatar
Russell Taylor committed
#ifdef __APPLE__
#include <mach-o/dyld.h>
Russell Taylor's avatar
Russell Taylor committed
#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 " +
         std::string(Mantid::Kernel::MantidVersion::version()) +
         "\nPlease cite: " + Mantid::Kernel::MantidVersion::paperCitation() +
         " and this release: " + Mantid::Kernel::MantidVersion::doi();
namespace Kernel {
namespace { // anonymous namespace for some utility functions

/// static Logger object
Logger g_log("ConfigService");

/**
 * Split the supplied string on semicolons.
 *
 * @param path The path to split.
 * @returns vector containing the splitted path.
std::vector<std::string> splitPath(const std::string &path) {
  std::vector<std::string> splitted;

  if (path.find(';') == std::string::npos) { // don't bother tokenizing
    splitted.push_back(path);
  } else {
    int options = Mantid::Kernel::StringTokenizer::TOK_TRIM +
                  Mantid::Kernel::StringTokenizer::TOK_IGNORE_EMPTY;
    Mantid::Kernel::StringTokenizer tokenizer(path, ";,", options);
    auto iend = tokenizer.end();
    for (auto itr = tokenizer.begin(); itr != iend; ++itr) {
      if (!itr->empty()) {
        splitted.push_back(*itr);
      }
  return splitted;
}

} // end of anonymous namespace

/** 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); }
  template <typename Field> explicit WrappedObject(Field &F) : T(F) {
    m_pPtr = static_cast<T *>(this);
  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()
Hahn, Steven's avatar
Hahn, Steven committed
    : m_pConf(nullptr), m_pSysConfig(nullptr), m_changed_keys(),
      m_ConfigPaths(), m_AbsolutePaths(), m_strBaseDir(""),
      m_PropertyString(""), m_properties_file_name("Mantid.properties"),
      // Use a different user properties file for an mpi-enabled build to avoid
Nick Draper's avatar
Nick Draper committed
      // confusion if both are used on the same file system
      m_user_properties_file_name("Mantid-mpi.user.properties"),
      m_user_properties_file_name("Mantid.user.properties"),
      m_DataSearchDirs(), m_UserSearchDirs(), m_InstrumentDirs(),
      m_instr_prefixes(), m_proxyInfo(), m_isProxySet(false),
      m_filterChannels() {
  // getting at system details
  m_pSysConfig = new WrappedObject<Poco::Util::SystemConfiguration>;
  // Register the FilterChannel with the Poco logging factory
  Poco::LoggingFactory::defaultFactory().registerChannelClass(
      "FilterChannel",
      new Poco::Instantiator<Poco::FilterChannel, Poco::Channel>);
  // Register StdChannel with Poco
  Poco::LoggingFactory::defaultFactory().registerChannelClass(
      "StdoutChannel",
      new Poco::Instantiator<Poco::StdoutChannel, 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);
  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()) {
      // 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.emplace("mantidqt.python_interfaces_directory", true);
  m_ConfigPaths.emplace("plugins.directory", true);
  m_ConfigPaths.emplace("pvplugins.directory", true);
  m_ConfigPaths.emplace("mantidqt.plugins.directory", true);
  m_ConfigPaths.emplace("instrumentDefinition.directory", true);
  m_ConfigPaths.emplace("instrumentDefinition.vtpDirectory", true);
  m_ConfigPaths.emplace("groupingFiles.directory", true);
  m_ConfigPaths.emplace("maskFiles.directory", true);
  m_ConfigPaths.emplace("colormaps.directory", true);
  m_ConfigPaths.emplace("requiredpythonscript.directories", true);
  m_ConfigPaths.emplace("pythonscripts.directory", true);
  m_ConfigPaths.emplace("pythonscripts.directories", true);
  m_ConfigPaths.emplace("python.plugins.directories", true);
Loading
Loading full blame...