Newer
Older
Robert Whitley
committed
* a key or it couldn't be found.
*/
std::vector<std::string> ConfigServiceImpl::getKeys(const std::string& keyName) const
{
std::vector<std::string> rawKeys;
Robert Whitley
committed
std::vector<std::string> keyVector;
keyVector.reserve(rawKeys.size());
Robert Whitley
committed
try
{
m_pConf->keys(keyName,rawKeys);
// Work around a limitation of Poco < v1.4 which has no remove functionality so
// check those that have been marked with the correct flag
const size_t nraw = rawKeys.size();
for( size_t i = 0; i < nraw; ++i )
{
const std::string key = rawKeys[i];
try
{
if( m_pConf->getString(key) == m_removedFlag ) continue;
}
catch (Poco::NotFoundException&)
{
}
keyVector.push_back(key);
}
Robert Whitley
committed
}
catch (Poco::NotFoundException&)
{
g_log.debug() << "Unable to find " << keyName << " in the properties file" << std::endl;
keyVector.clear();
}
return keyVector;
}
Robert Whitley
committed
/** Removes a key from the memory stored properties file and inserts the key into the
* changed key list so that when the program calls saveConfig the properties file will
* be the same and not contain the key no more
*
* @param rootName :: The key that is to be deleted
Robert Whitley
committed
*/
void ConfigServiceImpl::remove(const std::string& rootName) const
{
try
{
// m_pConf->remove(rootName) will only work in Poco v >=1.4. Current Ubuntu and RHEL use 1.3.x
// Simulate removal by marking with a flag value
m_pConf->setString(rootName, m_removedFlag);
Robert Whitley
committed
}
catch (Poco::NotFoundException&)
{
g_log.debug() << "Unable to find " << rootName << " in the properties file" << std::endl;
}
m_changed_keys.insert(rootName);
}
/** Checks to see whether the given key exists.
*
* @param rootName :: The case sensitive key that you are looking to see if exists.
Robert Whitley
committed
* @returns Boolean value denoting whether the exists or not.
*/
bool ConfigServiceImpl::hasProperty(const std::string& rootName) const
{
// Work around a limitation of Poco < v1.4 which has no remove functionality
return m_pConf->hasProperty(rootName) && m_pConf->getString(rootName) != m_removedFlag;
Robert Whitley
committed
}
/** Checks to see whether the given file target is an executable one and it exists.
* This method will expand environment variables found in the given file path.
Robert Whitley
committed
*
* @param target :: The path to the file you wish to see whether it's an executable.
Robert Whitley
committed
* @returns Boolean value denoting whether the file is an executable or not.
*/
bool ConfigServiceImpl::isExecutable(const std::string& target) const
{
try
{
std::string expTarget = Poco::Path::expand(target);
Poco::File tempFile = Poco::File(expTarget);
Robert Whitley
committed
if (tempFile.exists())
{
if(tempFile.canExecute())
return true;
else
return false;
}
else
return false;
}
catch(Poco::Exception&)
{
return false;
}
}
Robert Whitley
committed
/** Runs a command line string to open a program. The function can take program arguments.
* i.e it can load in a file to the program on startup.
*
* This method will expand environment variables found in the given file path.
*
Robert Whitley
committed
* @param programFilePath :: The directory where the program is located.
* @param programArguments :: The arguments that the program can take on startup. For example,
* the file to load up.
*/
void ConfigServiceImpl::launchProcess(const std::string& programFilePath, const std::vector<std::string>& programArguments) const
{
try
{
std::string expTarget = Poco::Path::expand(programFilePath);
Poco::Process::launch(expTarget, programArguments);
Robert Whitley
committed
}
catch(Poco::SystemException &e)
{
throw std::runtime_error(e.what());
}
}
Campbell, Stuart
committed
/**
* Set a configuration property. An existing key will have its value updated.
Janik Zikovsky
committed
* @param key :: The key to refer to this property
* @param value :: The value of the property
Campbell, Stuart
committed
*/
void ConfigServiceImpl::setString(const std::string & key, const std::string & value)
{
// If the value is unchanged (after any path conversions), there's nothing to do.
const std::string old = getString(key);
if ( value == old ) return;
Janik Zikovsky
committed
Campbell, Stuart
committed
//Ensure we keep a correct full path
std::map<std::string, bool>::const_iterator itr = m_ConfigPaths.find(key);
if (itr != m_ConfigPaths.end())
Campbell, Stuart
committed
m_AbsolutePaths[key] = makeAbsolute(value, key);
Gigg, Martyn Anthony
committed
if (key == "datasearch.directories" )
Campbell, Stuart
committed
cacheDataSearchPaths();
else if (key == "usersearch.directories")
{
cacheUserSearchPaths();
}
else if (key == "instrumentDefinition.directory")
{
cacheInstrumentPaths();
else if (key == "defaultsave.directory")
{
Gigg, Martyn Anthony
committed
appendDataSearchDir(value);
}
Campbell, Stuart
committed
m_pConf->setString(key, value);
Janik Zikovsky
committed
m_notificationCenter.postNotification(new ValueChanged(key, value, old));
m_changed_keys.insert(key);
Campbell, Stuart
committed
}
/** Searches for a string within the currently loaded configuaration values and
* attempts to convert the values to the template type supplied.
*
Janik Zikovsky
committed
* @param keyName :: The case sensitive name of the property that you need the value of.
* @param out :: The value if found
Campbell, Stuart
committed
* @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);
Janik Zikovsky
committed
int result = Mantid::Kernel::Strings::convert(strValue, out);
Campbell, Stuart
committed
return result;
}
/**
* Return the full filename of the local properties file.
* @returns A string containing the full path to the local file.
*/
std::string ConfigServiceImpl::getLocalFilename() const
{
#ifdef _WIN32
return "Mantid.local.properties";
#else
return "/etc/mantid.local.properties";
#endif
}
Campbell, Stuart
committed
/**
* Return the full filename of the user properties file
* @returns A string containing the full path to the user file
Campbell, Stuart
committed
*/
std::string ConfigServiceImpl::getUserFilename() const
{
Gigg, Martyn Anthony
committed
return getUserPropertiesDir() + m_user_properties_file_name;
Campbell, Stuart
committed
}
/** Searches for the string within the environment variables and returns the
* value as a string.
*
Janik Zikovsky
committed
* @param keyName :: The name of the environment variable that you need the value of.
Campbell, Stuart
committed
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
* @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");
}
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
/// @returns true if the file exists and can be read
bool canRead(const std::string &filename) {
// check for existence of the file
Poco::File pocoFile(filename);
if (!pocoFile.exists()) {
return false;
}
// just return if it is readable
return pocoFile.canRead();
}
/**
* Gets the name of the operating system version in a human readable form.
*
* @returns The operating system desciption
*/
std::string ConfigServiceImpl::getOSVersionReadable() {
std::string description;
#ifdef __linux__
// read os-release
static const std::string OS_RELEASE("/etc/os-release");
if (canRead(OS_RELEASE)) {
static const std::string PRETTY_NAME("PRETTY_NAME=");
// open it to see if it has the magic line
std::ifstream handle(OS_RELEASE.c_str(), std::ios::in);
// go through the file
std::string line;
while (std::getline(handle, line)) {
if (line.find(PRETTY_NAME) != std::string::npos) {
if (line.length() > PRETTY_NAME.length() + 1) {
size_t length = line.length() - PRETTY_NAME.length() - 2;
description = line.substr(PRETTY_NAME.length() + 1, length);
}
break;
}
}
// cleanup
handle.close();
if (!description.empty()) {
return description;
}
}
// read redhat-release
static const std::string REDHAT_RELEASE("/etc/redhat-release");
if (canRead(REDHAT_RELEASE)) {
// open it to see if it has the magic line
std::ifstream handle(REDHAT_RELEASE.c_str(), std::ios::in);
// go through the file
std::string line;
while (std::getline(handle, line)) {
if (!line.empty()) {
description = line;
break;
}
}
// cleanup
handle.close();
if (!description.empty()) {
return description;
}
}
#endif
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
// try system calls
std::string cmd;
std::vector<std::string> args;
#ifdef __APPLE__
cmd = "sw_vers"; // mac
#elif _WIN32
cmd = "wmic"; // windows
args.push_back("os"); // windows
args.push_back("get"); // windows
args.push_back("Caption"); // windows
args.push_back("/value"); // windows
#endif
if (!cmd.empty()) {
try {
Poco::Pipe outPipe, errorPipe;
Poco::ProcessHandle ph =
Poco::Process::launch(cmd, args, 0, &outPipe, &errorPipe);
const int rc = ph.wait();
// Only if the command returned successfully.
if (rc == 1) {
Poco::PipeInputStream pipeStream(outPipe);
std::stringstream stringStream;
Poco::StreamCopier::copyStream(pipeStream, stringStream);
// TODO process the result
// std::cout << "***" << stringStream.str() << "***" <<
// std::endl;
} else {
std::stringstream messageStream;
messageStream << "command \"" << cmd << "\" failed with code: " << rc;
g_log.debug(messageStream.str());
}
}
catch (Poco::SystemException &e) {
g_log.debug("command \"" + cmd + "\" failed");
g_log.debug(e.what());
}
}
return description;
}
/// @returns The name of the current user as reported by the environment.
std::string ConfigServiceImpl::getUsername() {
std::string username;
// mac and favorite way to get username on linux
try {
username = m_pSysConfig->getString("system.env.USER");
if (!username.empty()) {
return username;
}
}
catch (Poco::NotFoundException &e) {
UNUSED_ARG(e); // let it drop on the floor
}
// windoze and alternate linux username variable
try {
username = m_pSysConfig->getString("system.env.USERNAME");
if (!username.empty()) {
return username;
}
catch (Poco::NotFoundException &e) {
UNUSED_ARG(e); // let it drop on the floor
// give up and return an empty string
return std::string();
}
Campbell, Stuart
committed
/** 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 current directory containing the dll. Const version.
*
* @returns The absolute path of the current directory containing the dll
*/
std::string ConfigServiceImpl::getCurrentDir() const
{
return m_pSysConfig->getString("system.currentDir");
}
Campbell, Stuart
committed
/** 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");
}
/** Gets the absolute path of the appdata directory
*
* @returns The absolute path of the appdata directory
*/
std::string ConfigServiceImpl::getAppDataDir()
{
const std::string applicationName = "mantid";
#if POCO_OS == POCO_OS_WINDOWS_NT
const std::string vendorName = "mantidproject";
std::string appdata = std::getenv("APPDATA");
Poco::Path path(appdata);
path.makeDirectory();
path.pushDirectory(vendorName);
path.pushDirectory(applicationName);
return path.toString();
#else //linux and mac
Poco::Path path(Poco::Path::home());
path.pushDirectory("." + applicationName);
return path.toString();
#endif
}
Gigg, Martyn Anthony
committed
/**
* Get the directory containing the program executable
* @returns A string containing the path of the directory
* containing the executable, including a trailing slash
*/
std::string ConfigServiceImpl::getDirectoryOfExecutable() const
Gigg, Martyn Anthony
committed
{
return Poco::Path(getPathToExecutable()).parent().toString();
}
/**
* Get the full path to the executing program (i.e. whatever Mantid is embedded in)
* @returns A string containing the full path the the executable
*/
std::string ConfigServiceImpl::getPathToExecutable() const
Gigg, Martyn Anthony
committed
{
std::string execpath("");
const size_t LEN(1024);
// cppcheck-suppress variableScope
Gigg, Martyn Anthony
committed
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
char pBuf[LEN];
#ifdef _WIN32
unsigned int bytes = GetModuleFileName(NULL, pBuf, LEN);
#elif defined __linux__
char szTmp[32];
sprintf(szTmp, "/proc/%d/exe", getpid());
ssize_t bytes = readlink(szTmp, pBuf, LEN);
#elif defined __APPLE__
// Two calls to _NSGetExecutablePath required - first to get size of buffer
uint32_t bytes(0);
_NSGetExecutablePath(pBuf,&bytes);
const int success = _NSGetExecutablePath(pBuf,&bytes);
if (success < 0) bytes = 1025;
#endif
if( bytes > 0 && bytes < 1024 )
{
pBuf[bytes] = '\0';
execpath = std::string(pBuf);
}
return execpath;
}
/**
* Check if the path is on a network drive
* @param path :: The path to be checked
* @return True if the path is on a network drive.
*/
bool ConfigServiceImpl::isNetworkDrive(const std::string & path)
{
#ifdef _WIN32
// if path is relative get the full one
char buff[MAX_PATH];
GetFullPathName(path.c_str(),MAX_PATH,buff,NULL);
std::string fullName(buff);
size_t i = fullName.find(':');
// if the full path doesn't contain a drive letter assume it's on the network
if (i == std::string::npos) return true;
fullName.erase(i+1);
fullName += '\\'; // make sure the name has the trailing backslash
UINT type = GetDriveType(fullName.c_str());
return DRIVE_REMOTE == type;
#elif defined __linux__
// This information is only present in the /proc/mounts file on linux. There are no drives on
// linux only mount locations therefore the test will have to check the path against
// entries in /proc/mounts to see if the filesystem type is NFS or SMB (any others ????)
// Each line corresponds to a particular mounted location
// 1st column - device name
// 2nd column - mounted location
// 3rd column - filesystem type commonly ext2, ext3 for hard drives and NFS or SMB for
// network locations
std::ifstream mntfile("/proc/mounts");
std::string txtread("");
while( getline(mntfile, txtread) )
{
std::istringstream strm(txtread);
std::string devname(""), mntpoint(""), fstype("");
strm >> devname >> mntpoint >> fstype;
if( !strm ) continue;
// I can't be sure that the file system type is always lower case
std::transform(fstype.begin(), fstype.end(), fstype.begin(), toupper);
// Skip the current line if the file system isn't a network one
if( fstype != "NFS" && fstype != "SMB" ) continue;
// Now we have a line containing a network filesystem and just need to check if the path
// supplied contains the mount location. There is a small complication in that the mount
// points within the file have certain characters transformed into their octal
// representations, for example spaces->040.
std::string::size_type idx = mntpoint.find("\\0");
if( idx != std::string::npos )
{
std::string oct = mntpoint.substr(idx + 1, 3);
strm.str(oct);
int printch(-1);
strm.setf( std::ios::oct, std::ios::basefield );
strm >> printch;
if( printch != -1 )
{
mntpoint = mntpoint.substr(0, idx) + static_cast<char>(printch) + mntpoint.substr(idx + 4);
}
// Search for this at the start of the path
if( path.find(mntpoint) == 0 ) return true;
}
}
return false;
#else
Gigg, Martyn Anthony
committed
// Not yet implemented for the mac
return false;
#endif
}
/**
* Set the environment variable for the PV_PLUGIN_PATH based on where Mantid is.
*/
void ConfigServiceImpl::setParaViewPluginPath() const
{
std::string mantid_loc = this->getDirectoryOfExecutable();
Poco::Path pv_plugin_path(mantid_loc + "/pvplugins/pvplugins"); // Developer build paths
pv_plugin_path = pv_plugin_path.absolute();
g_log.debug() << "Trying " << pv_plugin_path.toString() << " as PV_PLUGIN_PATH\n";
Poco::File pv_plugin(pv_plugin_path.toString());
if (!pv_plugin.exists() || !pv_plugin.isDirectory())
{
// Installation paths
g_log.debug("ParaView plugin directory \"" + pv_plugin.path() + "\" does not exist. Trying properties file location.");
std::string user_loc = this->getString("pvplugins.directory");
if(user_loc.empty())
{
g_log.debug("No ParaView plugin directory specified in the properties file.");
return; // it didn't work
}
pv_plugin_path = Poco::Path(user_loc, "pvplugins");
pv_plugin_path = pv_plugin_path.absolute();
pv_plugin = Poco::File(pv_plugin_path.toString());
if (!pv_plugin.exists() || !pv_plugin.isDirectory())
{
g_log.debug("ParaView plugin directory \"" + pv_plugin.path() + "\" does not exist");
return; // it didn't work
}
// one of the two choices worked so set to that directory
g_log.debug("Setting PV_PLUGIN_PATH = \"" + pv_plugin.path() + "\"");
Poco::Environment::set("PV_PLUGIN_PATH", pv_plugin.path());
}
Gigg, Martyn Anthony
committed
Campbell, Stuart
committed
/**
Gigg, Martyn Anthony
committed
* Gets the directory that we consider to be the directory containing the Mantid.properties file.
* Basically, this is the either the directory pointed to by MANTIDPATH or the directory of the current
* executable if this is not set.
Campbell, Stuart
committed
* @returns The directory to consider as the base directory, including a trailing slash
*/
Gigg, Martyn Anthony
committed
std::string ConfigServiceImpl::getPropertiesDir() const
Campbell, Stuart
committed
{
return m_strBaseDir;
}
/**
Gigg, Martyn Anthony
committed
* Return the directory that Mantid should use for writing any files it needs so that
* this is kept separated to user saved files. A trailing slash is appended
Campbell, Stuart
committed
* so that filenames can more easily be concatenated with this
* @return the directory that Mantid should use for writing files
*/
Gigg, Martyn Anthony
committed
std::string ConfigServiceImpl::getUserPropertiesDir() const
Campbell, Stuart
committed
{
Gigg, Martyn Anthony
committed
#ifdef _WIN32
Campbell, Stuart
committed
return m_strBaseDir;
#else
Poco::Path datadir(m_pSysConfig->getString("system.homeDir"));
datadir.append(".mantid");
// Create the directory if it doesn't already exist
Poco::File(datadir).createDirectory();
return datadir.toString() + "/";
#endif
}
Campbell, Stuart
committed
/**
* Return the list of search paths
* @returns A vector of strings containing the defined search directories
*/
const std::vector<std::string>& ConfigServiceImpl::getDataSearchDirs() const
{
return m_DataSearchDirs;
}
Gigg, Martyn Anthony
committed
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
/**
* Set a list of search paths via a vector
* @param searchDirs :: A list of search directories
*/
void ConfigServiceImpl::setDataSearchDirs(const std::vector<std::string> &searchDirs)
{
std::string searchPaths = boost::join(searchDirs, ";");
setDataSearchDirs(searchPaths);
}
/**
* Set a list of search paths via a string
* @param searchDirs :: A string containing a list of search directories separated by a semi colon (;).
*/
void ConfigServiceImpl::setDataSearchDirs(const std::string &searchDirs)
{
setString("datasearch.directories", searchDirs);
}
/**
* 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)
{
if ( path.empty() ) return;
Gigg, Martyn Anthony
committed
Poco::Path dirPath;
try
{
dirPath = Poco::Path(path);
dirPath.makeDirectory();
}
catch(Poco::PathSyntaxException &)
{
return;
}
if (!isInDataSearchList(dirPath.toString()))
Gigg, Martyn Anthony
committed
{
std::string newSearchString;
std::vector<std::string>::const_iterator it = m_DataSearchDirs.begin();
Janik Zikovsky
committed
for (; it != m_DataSearchDirs.end(); ++it)
Gigg, Martyn Anthony
committed
{
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 directories for XML instrument definition files (IDFs)
* @returns An ordered list of paths for instrument searching
*/
const std::vector<std::string>& ConfigServiceImpl::getInstrumentDirectories() const
{
return m_InstrumentDirs;
}
/**
* Return the base search directories for XML instrument definition files (IDFs)
* @returns a last entry of getInstrumentDirectories
*/
const std::string ConfigServiceImpl::getInstrumentDirectory() const
Campbell, Stuart
committed
{
return m_InstrumentDirs[m_InstrumentDirs.size()-1];
}
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
/**
* Fills the internal cache of instrument definition directories
*/
void ConfigServiceImpl::cacheInstrumentPaths()
{
m_InstrumentDirs.clear();
Poco::Path path(getAppDataDir());
path.makeDirectory();
path.pushDirectory("instrument");
std::string appdatadir = path.toString();
addDirectoryifExists(appdatadir,m_InstrumentDirs);
#ifndef _WIN32
std::string etcdatadir = "/etc/mantid/instrument";
addDirectoryifExists(etcdatadir,m_InstrumentDirs);
#endif
// 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();
}
addDirectoryifExists(directoryName,m_InstrumentDirs);
}
/**
* Verifies the directory exists and add it to the back of the directory list if valid
* @param directoryName the directory name to add
* @param directoryList the list to add the directory to
* @returns true if the directory was valid and added to the list
*/
bool ConfigServiceImpl::addDirectoryifExists(const std::string& directoryName, std::vector<std::string>& directoryList)
{
try
if (Poco::File(directoryName).isDirectory())
{
directoryList.push_back(directoryName);
return true;
}
else
{
g_log.information("Unable to locate directory at: " + directoryName);
return false;
}
catch (Poco::PathNotFoundException&)
{
g_log.information("Unable to locate directory at: " + directoryName);
return false;
}
catch (Poco::FileNotFoundException&)
{
g_log.information("Unable to locate directory at: " + directoryName);
return false;
}
Campbell, Stuart
committed
}
/**
* Load facility information from instrumentDir/Facilities.xml file if fName parameter
* is not set
Janik Zikovsky
committed
* @param fName :: An alternative file name for loading facilities information.
Campbell, Stuart
committed
*/
void ConfigServiceImpl::updateFacilities(const std::string& fName)
{
clearFacilities();
Campbell, Stuart
committed
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::AutoPtr<Poco::XML::Document> pDoc;
Roman Tolchenov
committed
Campbell, Stuart
committed
try
Roman Tolchenov
committed
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())
{
throw std::runtime_error("No root element in Facilities.xml file");
}
Poco::AutoPtr<Poco::XML::NodeList> pNL_facility = pRootElem->getElementsByTagName("facility");
unsigned long n = pNL_facility->length();
Campbell, Stuart
committed
for (unsigned long i = 0; i < n; ++i)
Roman Tolchenov
committed
{
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())
Roman Tolchenov
committed
throw std::runtime_error("The facility definition file " + fileName + " defines no facilities");
Janik Zikovsky
committed
} catch (std::exception& e)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
g_log.error(e.what());
Roman Tolchenov
committed
}
Campbell, Stuart
committed
}
/// Empty the list of facilities, deleting the FacilityInfo objects in the process
void ConfigServiceImpl::clearFacilities()
{
for (auto it = m_facilities.begin(); it != m_facilities.end(); ++it)
{
delete *it;
}
m_facilities.clear();
}
/**
* Returns instruments with given name
* @param instrumentName 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);
Gigg, Martyn Anthony
committed
catch (Exception::NotFoundError &)
{
// 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);
Gigg, Martyn Anthony
committed
catch (Exception::NotFoundError &)
{
// Well the instName doesn't exist for this facility...
// Move along, there's nothing to see here...
}
}
g_log.debug("Instrument " + instrumentName + " not found");
throw Exception::NotFoundError("Instrument", instrumentName);
}
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
/** Gets a vector of the facility Information objects
* @return A vector of FacilityInfo objects
*/
const std::vector<FacilityInfo*> ConfigServiceImpl::getFacilities() const
{
return m_facilities;
}
/** Gets a vector of the facility names
* @return A vector of the facility Names
*/
const std::vector<std::string> ConfigServiceImpl::getFacilityNames()const
{
auto names = std::vector<std::string>(m_facilities.size());
auto itFacilities = m_facilities.begin();
auto itNames = names.begin();
for (; itFacilities != m_facilities.end(); ++itFacilities,++itNames)
{
*itNames = (**itFacilities).name();
}
return names;
}
/** Get the default facility
* @return the facility information object
Campbell, Stuart
committed
*/
const FacilityInfo& ConfigServiceImpl::getFacility() const
Campbell, Stuart
committed
{
std::string defFacility = getString("default.facility");
if (defFacility.empty())
Roman Tolchenov
committed
{
Campbell, Stuart
committed
defFacility = "ISIS";
Roman Tolchenov
committed
}
Michael Whitty
committed
}
Campbell, Stuart
committed
/**
* Get a facility
* @param facilityName :: Facility name
* @return the facility information object
Janik Zikovsky
committed
* @throw NotFoundException if the facility is not found
Campbell, Stuart
committed
*/
const FacilityInfo& ConfigServiceImpl::getFacility(const std::string& facilityName) const
Campbell, Stuart
committed
{
if (facilityName.empty())
return this->getFacility();
Campbell, Stuart
committed
std::vector<FacilityInfo*>::const_iterator it = m_facilities.begin();
for (; it != m_facilities.end(); ++it)
Roman Tolchenov
committed
{
if ((**it).name() == facilityName)
Roman Tolchenov
committed
{
Campbell, Stuart
committed
return **it;
Roman Tolchenov
committed
}
}
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
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);
Campbell, Stuart
committed
}
/*
Ammend paths to point to include the paraview core libraries.
@param path : path to add
*/
void ConfigServiceImpl::setParaviewLibraryPath(const std::string& path)
{
#ifdef _WIN32
const std::string platformPathName = "PATH";
Poco::Path existingPath;
char separator = existingPath.pathSeparator();
std::string strSeparator;
strSeparator.push_back(separator);
if(Poco::Environment::has(platformPathName))
{
existingPath = Poco::Environment::get(platformPathName);
existingPath.append(strSeparator + path);