Newer
Older
Gigg, Martyn Anthony
committed
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
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
// Not yet implemented for the mac
return false;
#endif
}
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
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
/**
* 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)
{
Janik Zikovsky
committed
if (!isInDataSearchList(path))
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 directory for XML instrument definition files (IDFs)
* @returns Full path of instrument search directory
*/
const std::string ConfigServiceImpl::getInstrumentDirectory() const
Campbell, Stuart
committed
{
// Determine the search directory for XML instrument definition files (IDFs)
std::string directoryName = getString("instrumentDefinition.directory");
if (directoryName.empty())
Campbell, Stuart
committed
// 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();
Janik Zikovsky
committed
if (!Poco::File(directoryName).isDirectory())
g_log.error("Unable to locate instrument search directory at: " + directoryName);
return directoryName;
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)
{
m_facilities.clear();
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::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())
{
pDoc->release();
throw std::runtime_error("No root element in Facilities.xml file");
}
Roman Tolchenov
committed
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
pNL_facility->release();
pDoc->release();
throw std::runtime_error("The facility definition file " + fileName + " defines no facilities");
Janik Zikovsky
committed
Roman Tolchenov
committed
pNL_facility->release();
pDoc->release();
Janik Zikovsky
committed
} catch (std::exception& e)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
g_log.error(e.what());
Roman Tolchenov
committed
}
Campbell, Stuart
committed
}
/**
* 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);
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
}
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
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
}
return getFacility(defFacility);
Michael Whitty
committed
}
Campbell, Stuart
committed
/**
* Get a facility
Janik Zikovsky
committed
* @param fName :: 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
}
}
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
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
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);
Campbell, Stuart
committed
}
/// \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&);
template DLLExport int ConfigServiceImpl::getValue(const std::string&, std::size_t&);
Campbell, Stuart
committed
/// \endcond TEMPLATE
} // namespace Kernel
} // namespace Mantid