Skip to content
Snippets Groups Projects
ConfigService.cpp 54.2 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
{

namespace { // anonymous namespace for some utility functions

/**
 * Split the supplied string on semicolons.
 *
 * @param path The path to split.
 * @param splitted vector to put the splitted path into.
 */
void splitPath(const std::string &path, std::vector<std::string> &splitted)
{
  if (path.find(";") == std::string::npos)
  {  // don't bother tokenizing
    splitted.push_back(path);
    return;
  }

  int options = Poco::StringTokenizer::TOK_TRIM + Poco::StringTokenizer::TOK_IGNORE_EMPTY;

  splitted.clear();
  Poco::StringTokenizer tokenizer(path, ";,", options);
  Poco::StringTokenizer::Iterator iend = tokenizer.end();
  splitted.reserve(tokenizer.count());
  for (Poco::StringTokenizer::Iterator itr = tokenizer.begin(); itr != iend; ++itr)
  {
    if (!itr->empty())
    {
      splitted.push_back(*itr);
    }
  }
}

/**
 * Verify that two paths are equal. This can be two directories or two
 * semicolon separated paths.
 *
 * @param left The left path for comparison.
 * @param right The right path for comparison.
 *
 * @return True if the paths match.
 */
bool pathsEqual(const std::string &left, const std::string &right)
{
  if (left == right)
    return true;

  // deal with silly case of empty paths
  if (left.empty())
    return false;
  if (right.empty())
    return false;

  // check for path rather than simple directory
  if ((left.find(";") != std::string::npos) || (right.find(";") != std::string::npos))
  {
    // at least one has a semicolons

    std::vector<std::string> leftDirs;
    splitPath(left, leftDirs);

    std::vector<std::string> rightDirs;
    splitPath(right, rightDirs);

    // confirm they have the same number of items
    if (leftDirs.size() != rightDirs.size())
      return false;

    // sort the vectors
    std::sort(leftDirs.begin(), leftDirs.end());
    std::sort(rightDirs.begin(), rightDirs.end());

    // assume that they are in the same order now
    std::size_t numpaths = leftDirs.size();
    for (std::size_t i = 0; i < numpaths; i++)
    {
      if (!pathsEqual(leftDirs[i], rightDirs[i]))
        return false;
    }
    return true;
  }

  Poco::File leftDir(left);
  if (!leftDir.isDirectory())
    return false;
  Poco::File rightDir(right);
  if (!rightDir.isDirectory())
    return false;

  return (leftDir == rightDir);
}

} // 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);
  }

  /** 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;
  }
Loading
Loading full blame...