Skip to content
Snippets Groups Projects
ConfigService.cpp 38.8 KiB
Newer Older
/**
 *  Adds the passed path to the end of the list of data search paths
 *  the path name must be absolute
 *  @param path :: the absolute path to add
 */
void ConfigServiceImpl::appendDataSearchDir(const std::string & path)
{
  {
    std::string newSearchString;
    std::vector<std::string>::const_iterator it = m_DataSearchDirs.begin();
    for (; it != m_DataSearchDirs.end(); ++it)
    {
      newSearchString.append(*it);
      newSearchString.append(";");
    }
    newSearchString.append(path);
    setString("datasearch.directories", newSearchString);
  }
}

/**
 * Return the list of user search paths
 * @returns A vector of strings containing the defined search directories
 */
const std::vector<std::string>& ConfigServiceImpl::getUserSearchDirs() const
{
  return m_UserSearchDirs;
}

/**
 * Return the search directory for XML instrument definition files (IDFs)
 * @returns Full path of instrument search directory
 */
const std::string ConfigServiceImpl::getInstrumentDirectory() const
{
  // Determine the search directory for XML instrument definition files (IDFs)
  std::string directoryName = getString("instrumentDefinition.directory");
  if (directoryName.empty())
    // This is the assumed deployment directory for IDFs, where we need to be relative to the
    // directory of the executable, not the current working directory.
    directoryName = Poco::Path(getPropertiesDir()).resolve("../instrument").toString();
  if (!Poco::File(directoryName).isDirectory())
    g_log.error("Unable to locate instrument search directory at: " + directoryName);
}

/**
 * Load facility information from instrumentDir/Facilities.xml file if fName parameter
 * is not set
 * @param fName :: An alternative file name for loading facilities information.
 */
void ConfigServiceImpl::updateFacilities(const std::string& fName)
{
  m_facilities.clear();
  std::string instrDir = getString("instrumentDefinition.directory");
  std::string fileName = fName.empty() ? instrDir + "Facilities.xml" : fName;

  // Set up the DOM parser and parse xml file
  Poco::XML::DOMParser pParser;
  Poco::XML::Document* pDoc;
    try
    {
      pDoc = pParser.parse(fileName);
    } catch (...)
    {
      throw Kernel::Exception::FileError("Unable to parse file:", fileName);
    }
    // Get pointer to root element
    Poco::XML::Element* pRootElem = pDoc->documentElement();
    if (!pRootElem->hasChildNodes())
    {
      pDoc->release();
      throw std::runtime_error("No root element in Facilities.xml file");
    }
    Poco::XML::NodeList* pNL_facility = pRootElem->getElementsByTagName("facility");
    unsigned long n = pNL_facility->length();
    for (unsigned long i = 0; i < n; ++i)
    {
      Poco::XML::Element* elem = dynamic_cast<Poco::XML::Element*> (pNL_facility->item(i));
      if (elem)
      {
        m_facilities.push_back(new FacilityInfo(elem));
      }
    }

    if (m_facilities.empty())
      pNL_facility->release();
      pDoc->release();
      throw std::runtime_error("The facility definition file " + fileName + " defines no facilities");
/**
 * Returns instruments with given name
 * @param  iName Instrument name
 * @return the instrument information object
 * @throw NotFoundError if iName was not found
 */
const InstrumentInfo & ConfigServiceImpl::getInstrument(const std::string& instrumentName) const
{

  // Let's first search for the instrument in our default facility
  std::string defaultFacility = ConfigService::Instance().getFacility().name();

  if (!defaultFacility.empty())
  {
    try
    {
      g_log.debug() << "Looking for " << instrumentName << " at " << defaultFacility << "." << std::endl;
      return getFacility(defaultFacility).Instrument(instrumentName);
    }
    catch (Exception::NotFoundError e)
    {
      // Well the instName doesn't exist for this facility
      // Move along, there's nothing to see here...
    }
  }

  // Now let's look through the other facilities
  std::vector<FacilityInfo*>::const_iterator it = m_facilities.begin();
  for (; it != m_facilities.end(); ++it)
  {
    try
    {
      g_log.debug() << "Looking for " << instrumentName << " at " << (**it).name() << "." << std::endl;
      return (**it).Instrument(instrumentName);
    }
    catch (Exception::NotFoundError e)
    {
      // Well the instName doesn't exist for this facility...
      // Move along, there's nothing to see here...
    }
  }
  g_log.error("Instrument " + instrumentName + " not found");
  throw Exception::NotFoundError("Instrument", instrumentName);
}

/** Get the default facility
 * @return the facility information object
const FacilityInfo& ConfigServiceImpl::getFacility() const
{
  std::string defFacility = getString("default.facility");
  if (defFacility.empty())
  return getFacility(defFacility);
 * @return the facility information object
 * @throw NotFoundException if the facility is not found
const FacilityInfo& ConfigServiceImpl::getFacility(const std::string& facilityName) const
{
  std::vector<FacilityInfo*>::const_iterator it = m_facilities.begin();
  for (; it != m_facilities.end(); ++it)
    if ((**it).name() == facilityName)
  g_log.error("Facility " + facilityName + " not found");
  throw Exception::NotFoundError("Facilities", facilityName);
}

/**
 * Set the default facility
 * @param facilityName the facility name
 * @throw NotFoundException if the facility is not found
 */
void ConfigServiceImpl::setFacility(const std::string &facilityName)
{
  bool found = false;
  // Look through the facilities for a matching one.
  std::vector<FacilityInfo*>::const_iterator it = m_facilities.begin();
  for (; it != m_facilities.end(); ++it)
  {
    if ((**it).name() == facilityName)
    {
      // Found the facility
      found = true;
      // So it's safe to set it as our default
      setString("default.facility", facilityName);
    }
  }
  if (found == false)
  {
    g_log.error("Failed to set default facility to be " + facilityName + ". Facility not found");
    throw Exception::NotFoundError("Facilities", facilityName);
  }

}

/**  Add an observer to a notification
 @param observer :: Reference to the observer to add
 */
void ConfigServiceImpl::addObserver(const Poco::AbstractObserver& observer) const
{
  m_notificationCenter.addObserver(observer);
}

/**  Remove an observer
 @param observer :: Reference to the observer to remove
 */
void ConfigServiceImpl::removeObserver(const Poco::AbstractObserver& observer) const
{
  m_notificationCenter.removeObserver(observer);
}

/// \cond TEMPLATE
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&);
Peterson, Peter's avatar
Peterson, Peter committed
template DLLExport int ConfigServiceImpl::getValue(const std::string&, std::size_t&);

} // namespace Kernel
} // namespace Mantid