8#include <Poco/DirectoryIterator.h>
11#include <Poco/SAX/Attributes.h>
12#include <Poco/SAX/ContentHandler.h>
13#include <Poco/SAX/SAXParser.h>
14#include <boost/algorithm/string/find.hpp>
15#include <boost/regex.hpp>
32 std::string m_validFrom;
33 std::string m_validTo;
34 DummyException(std::string validFrom, std::string validTo)
35 : m_validFrom(
std::move(validFrom)), m_validTo(
std::move(validTo)) {}
38class myContentHandler :
public Poco::XML::ContentHandler {
39 void startElement(
const XMLString & ,
const XMLString &localName,
const XMLString & ,
40 const Attributes &attrList)
override {
41 if (localName ==
"instrument" || localName ==
"parameter-file") {
42 throw DummyException(
static_cast<std::string
>(attrList.getValue(
"",
"valid-from")),
43 static_cast<std::string
>(attrList.getValue(
"",
"valid-to")));
46 void endElement(
const XMLString & ,
const XMLString & ,
const XMLString & )
override {}
47 void startDocument()
override {}
48 void endDocument()
override {}
49 void characters(
const XMLChar [],
int ,
int )
override {}
50 void endPrefixMapping(
const XMLString & )
override {}
51 void ignorableWhitespace(
const XMLChar [],
int ,
int )
override {}
52 void processingInstruction(
const XMLString & ,
const XMLString & )
override {}
53 void setDocumentLocator(
const Locator * )
override {}
54 void skippedEntity(
const XMLString & )
override {}
55 void startPrefixMapping(
const XMLString & ,
const XMLString & )
override {}
84 const std::vector<std::string> validFormats = {
"xml",
"nxs",
"hdf5"};
85 g_log.
debug() <<
"Looking for instrument file for " << instrumentName <<
" that is valid on '" << date <<
"'\n";
93 const std::vector<std::string> matchingFiles =
96 if (!matchingFiles.empty()) {
97 instFile = matchingFiles[0];
98 g_log.
debug() <<
"Instrument file selected is " << instFile <<
'\n';
100 g_log.
debug() <<
"No instrument file found\n";
111 Poco::Path filePath(instName);
112 const std::string filename = filePath.getFileName();
115 if (!dirHint.empty()) {
116 const std::string result =
lookupIPF(dirHint, filename);
117 if (!result.empty()) {
125 for (
const auto &dirName : directoryNames) {
128 const std::string result =
lookupIPF(dirName, filename);
129 if (!result.empty()) {
140 const std::string ext =
".xml";
142 boost::algorithm::ierase_all(filename, ext);
144 const std::string suffixSeperator(
"_Definition");
149 if (
auto sepPos = boost::algorithm::ifind_first(filename, suffixSeperator)) {
150 prefix = std::string(filename.begin(), sepPos.begin());
151 suffix = std::string(sepPos.end(), filename.end());
156 Poco::Path directoryPath(dir);
157 directoryPath.makeDirectory();
160 std::string fullPathParamIDF = directoryPath.setFileName(prefix +
"_Parameters" + suffix + ext).toString();
162 if (Poco::File(fullPathParamIDF).
exists()) {
163 return fullPathParamIDF;
166 fullPathParamIDF = directoryPath.setFileName(prefix +
"_Parameters" + ext).toString();
167 if (Poco::File(fullPathParamIDF).
exists()) {
168 return fullPathParamIDF;
190 const std::vector<std::string> &fileFormats,
191 const std::vector<std::string> &directoryNames,
192 const std::string &date) {
196 g_log.
debug() <<
"No date specified, using current date and time.\n";
197 const std::string now = Types::Core::DateAndTime::getCurrentTime().toISO8601String();
203 std::stringstream ss;
205 for (
size_t i = 0; i < fileFormats.size(); ++i) {
208 ss << fileFormats[i];
211 const std::string allFileFormats = ss.str();
213 const boost::regex regex(prefix +
".*\\." + allFileFormats, boost::regex_constants::icase);
214 Poco::DirectoryIterator end_iter;
217 DateAndTime refDate(
"1900-01-31 23:59:00");
219 DateAndTime refDateGoodFile(
"1900-01-31 23:59:00");
223 std::multimap<DateAndTime, std::string, std::greater<DateAndTime>> matchingFiles;
224 bool foundFile =
false;
225 std::string mostRecentFile;
226 for (
const auto &directoryName : directoryNames) {
229 for (Poco::DirectoryIterator dir_itr(directoryName); dir_itr != end_iter; ++dir_itr) {
231 const auto &filePath = dir_itr.path();
232 if (!filePath.isFile())
235 const std::string &l_filenamePart = filePath.getFileName();
236 if (regex_match(l_filenamePart, regex)) {
237 const auto &pathName = filePath.toString();
238 g_log.
debug() <<
"Found file: '" << pathName <<
"'\n";
240 std::string validFrom, validTo;
242 g_log.
debug() <<
"File '" << pathName <<
" valid dates: from '" << validFrom <<
"' to '" << validTo <<
"'\n";
244 DateAndTime to, from;
245 if (validFrom.length() > 0)
246 from.setFromISO8601(validFrom);
249 if (validTo.length() > 0)
250 to.setFromISO8601(validTo);
252 to.setFromISO8601(
"2100-01-01T00:00:00");
254 if (from <=
d &&
d <= to) {
256 matchingFiles.insert(std::pair<DateAndTime, std::string>(from, pathName));
259 if (!foundFile && (from >= refDate)) {
261 mostRecentFile = pathName;
268 std::vector<std::string> pathNames;
269 if (!matchingFiles.empty()) {
270 pathNames.reserve(matchingFiles.size());
272 std::transform(matchingFiles.begin(), matchingFiles.end(), std::back_inserter(pathNames),
273 [](
const auto &elem) { return elem.second; });
275 pathNames.emplace_back(std::move(mostRecentFile));
288 std::string &outValidTo) {
292 myContentHandler conHand;
293 pParser.setContentHandler(&conHand);
296 pParser.parse(IDFfilename);
297 }
catch (DummyException &e) {
298 outValidFrom = e.m_validFrom;
299 outValidTo = e.m_validTo;
static void getValidFromTo(const std::string &IDFfilename, std::string &outValidFrom, std::string &outValidTo)
Utility to retrieve the validity dates for the given IDF.
static std::vector< std::string > getResourceFilenames(const std::string &prefix, const std::vector< std::string > &fileFormats, const std::vector< std::string > &directoryNames, const std::string &date)
Utility to retrieve a resource file (IDF, Parameters, ..)
static std::string getParameterPath(const std::string &instName, const std::string &dirHint="")
Search instrument directories for Parameter file, return full path name if found, else "".
static std::string lookupIPF(const std::string &dir, std::string filename)
static std::string getInstrumentFilename(const std::string &instrumentName, const std::string &date="")
Get the IDF using the instrument name and date.
The ConfigService class provides a simple facade to access the Configuration functionality of the Man...
const std::vector< std::string > & getInstrumentDirectories() const
Get instrument search directories.
The Logger class is in charge of the publishing messages from the framework through various channels.
void debug(const std::string &msg)
Logs at debug level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Kernel::Logger g_log("ExperimentInfo")
static logger object
bool exists(::NeXus::File &file, const std::string &name)
Based on the current group in the file, does the named sub-entry exist?
Logger g_log("DateAndTime")